fix(types): constrain rendered/fetched URLs to http(s) (closes #210)#211
Merged
Conversation
z.url() accepts dangerous schemes (javascript:, data:, ftp:). uslmUrl is used to download content and sourceUrl is rendered directly as an href in the precedent UI (PrecedentDrawer.svelte, statute page), so a malformed/compromised value could yield a clickable javascript: link (XSS on click) or an off-protocol download. Add a shared HttpUrlSchema (z.url().refine(http(s))) and apply it to ReleasePointSchema.uslmUrl and CaseAnnotationSchema.sourceUrl. Tighten the web content collection's sourceUrl (was z.string()) to the same http(s)-or-empty constraint so bad data fails the content build loudly. Low real-world likelihood today (URLs are constructed from uscode.house.gov / courtlistener.com), but the scheme was previously unenforced at the schema/render boundary. New tests assert javascript: and ftp: are rejected for both fields. Closes #210 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Closes #210 (security hardening from the
packages/typesreview).Problem
z.url()accepts dangerous schemes (javascript:,data:,ftp:). Two fields validated with it reach sensitive sinks:CaseAnnotationSchema.sourceUrlis rendered directly as an href —PrecedentDrawer.svelte:93,145,statute/[...slug].astro:397→ ajavascript:value is XSS-on-click.ReleasePointSchema.uslmUrlis used to download content in the fetcher.The web content collection was even looser (
sourceUrl: z.string()).Fix
HttpUrlSchema = z.url().refine(http(s))inpackages/types, applied touslmUrlandsourceUrl.apps/web/src/content.config.ts:sourceUrltightened to http(s)-or-empty so malformed annotation data fails the content build loudly instead of rendering a bad href.Low real-world likelihood today (URLs are constructed from
uscode.house.gov/courtlistener.com), but the scheme was unenforced at the schema/render boundary — this closes it as defense-in-depth alongside #200/#207.Verification
z.url()acceptsjavascript:in this Zod version; the refined schema rejectsjavascript:/ftp:/garbage and accepts https.javascript:/ftp:foruslmUrlandjavascript:forsourceUrl.pnpm --filter @civic-source/types test(40),fetcher(123),annotatorall pass;pnpm build8/8. No fixture breakage (production URLs are https).🤖 Generated with Claude Code