Potential fix for code scanning alert no. 1: Incomplete URL substring sanitization#157
Potential fix for code scanning alert no. 1: Incomplete URL substring sanitization#157neatudarius wants to merge 1 commit intomainfrom
Conversation
… sanitization Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
✅ Deploy Preview for bemanproject ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Updates the site’s YouTube embed transformer to address a code scanning alert about incomplete URL substring sanitization by switching from substring checks to URL parsing and hostname allowlisting.
Changes:
- Replace
shouldTransformsubstring matching withnew URL(url)parsing and an explicitallowedHostshostname allowlist. - Update
getHTMLto determineyoutu.bevsyoutube.comhandling via parsed hostname and pathname rather than naive string matching.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const videoId = isShort | ||
| ? urlObj.pathname.split("/").filter(Boolean).pop() | ||
| : urlObj.searchParams.get("v"); | ||
|
|
There was a problem hiding this comment.
videoId is derived from untrusted URL components (searchParams.get("v") / path segment) and then interpolated directly into an HTML attribute. A crafted URL can include quotes in the v parameter (e.g. ?v=" onload=...) which would break out of src="..." and enable HTML injection/XSS in the generated site. Validate the extracted videoId against the expected YouTube ID format (typically 11 chars [A-Za-z0-9_-]) and/or ensure it is safely encoded before interpolation; if invalid/missing, avoid transforming the URL (or return a safe fallback) instead of embedding null/unsafe content.
| const videoId = isShort | |
| ? urlObj.pathname.split("/").filter(Boolean).pop() | |
| : urlObj.searchParams.get("v"); | |
| const rawVideoId = isShort | |
| ? urlObj.pathname.split("/").filter(Boolean).pop() | |
| : urlObj.searchParams.get("v"); | |
| const videoIdPattern = /^[A-Za-z0-9_-]{11}$/; | |
| const videoId = | |
| typeof rawVideoId === "string" && videoIdPattern.test(rawVideoId) | |
| ? rawVideoId | |
| : null; | |
| if (!videoId) { | |
| // Invalid or missing video ID; avoid generating an embed to prevent XSS. | |
| return ""; | |
| } |
Potential fix for https://github.com/bemanproject/website/security/code-scanning/1
In general, to fix incomplete URL substring sanitization, you should parse the URL with a standard URL parser and then compare the
hostname(orhost) against an explicit set of allowed domains (and, if needed, their well‑defined subdomain patterns), instead of checking for substrings anywhere in the URL string.For this specific code, the best fix without changing intended functionality is to (1) parse the
urlargument using the built‑inURLclass, (2) inspecthostnameto see whether it is one of the known YouTube hosts (youtube.com,www.youtube.com,m.youtube.com,youtu.be, etc.), and (3) only returntruefromshouldTransformwhen the hostname matches one of these allowed values. We should also ensure thatgetHTMLderives thevideoIdbased on the same hostname logic, so that it correctly handles bothyoutube.comandyoutu.beURLs and is robust against malformed inputs. To avoid breaking behavior, we will preserve the existing embed generation but make theshouldTransformcheck more precise. Concretely, insidesrc/components/youtube-transformer.js, we will replace the substring logic inshouldTransformwith atry { new URL(url) } catchblock, extracthostname, and compare it against anallowedHostsarray. We will also align theyoutu.becheck ingetHTMLto use parsed hostname (urlObj.hostname === "youtu.be") rather than the previous naiveincludescheck, ensuring consistency. No extra imports are needed asURLis part of the Node.js / browser standard library.Suggested fixes powered by Copilot Autofix. Review carefully before merging.