Skip to content

fix(@angular/build): escape prerender redirect URLs#33248

Open
SkyZeroZx wants to merge 1 commit into
angular:mainfrom
SkyZeroZx:fix-build
Open

fix(@angular/build): escape prerender redirect URLs#33248
SkyZeroZx wants to merge 1 commit into
angular:mainfrom
SkyZeroZx:fix-build

Conversation

@SkyZeroZx
Copy link
Copy Markdown
Contributor

Escape prerender redirect targets before embedding them in generated static
redirect pages.

This prevents attacker-controlled redirect URLs from breaking out of the meta
refresh, anchor href, or fallback text contexts and injecting HTML that could
lead to XSS.

Add server-routes static e2e coverage for an HTML-breaking redirect target.

@SkyZeroZx SkyZeroZx marked this pull request as ready for review May 25, 2026 00:17
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces HTML escaping for redirect URLs in static pages to prevent HTML injection vulnerabilities. It adds an escapeHtml utility and updates the generateRedirectStaticPage function to apply this escaping to both the meta refresh tag and the fallback link. Additionally, E2E tests have been included to verify the fix. The reviewer pointed out that while HTML escaping prevents tag injection, it does not protect against malicious URI schemes like javascript:, and recommended adding protocol validation for the redirect URL.

* @returns The HTML content of the static redirect page.
*/
export function generateRedirectStaticPage(url: string): string {
const escapedUrl = escapeHtml(url);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

While escapeHtml prevents HTML injection by escaping characters that could break out of the attribute or tag context, it does not protect against XSS via malicious URI schemes such as javascript:. If the redirect URL is attacker-controlled (as suggested in the PR description), an attacker could provide a javascript: URL that would still execute when the user clicks the fallback link or when the browser processes the meta refresh. Consider validating that the URL uses an allowed protocol (e.g. http:, https:, or is a relative path starting with /).

References
  1. Avoid placing a comma immediately after abbreviations like 'e.g.' in user-facing messages. (link)

Copy link
Copy Markdown
Contributor Author

@SkyZeroZx SkyZeroZx May 25, 2026

Choose a reason for hiding this comment

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

Fixed, now it should throw an exception if we find an invalid scheme (it was also wonder me this and I forgot that javascript: was also an executable, although it only happens if you click on the href, but meta redirect doesn't work)

Escape prerender redirect targets before embedding them in generated static
redirect pages.

This prevents attacker-controlled redirect URLs from breaking out of the meta
refresh, anchor href, or fallback text contexts and injecting HTML that could
lead to XSS.
Copy link
Copy Markdown
Collaborator

@alan-agius4 alan-agius4 left a comment

Choose a reason for hiding this comment

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

I have reservations about this change.

It assumes the attacker can already modify the source code on your machine or alter the database if the routes are built dynamically. If an attacker already has that level of access, they could inflict far worse damage anyway.

return text.replace(/[&<>"']/g, (character) => htmlEscapeCharacters[character]);
}

function validateRedirectUrl(url: string): string {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Validation shouldn't happen here, it should happen why before during the extraction phase.

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.

It assumes the attacker can already modify the source code on your machine or alter the database if the routes are built dynamically. If an attacker already has that level of access, they could inflict far worse damage anyway.

In this regard, it is possible that we might use a third-party API that could be compromised; if that happens, the impact, instead of affecting only one company/person, would extend far beyond that.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants