Description
Angular SSR can select server-route metadata from one route while Angular Router renders a different route when the request URL contains certain ambiguous path forms.
Example:
/profile;
/profile//public
In both cases, a route configured as RenderMode.Client can be unexpectedly rendered on the server while inheriting public cache headers from another ServerRoute.
Minimal Reproduction
Minimal configuration
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
{
path: 'profile',
renderMode: RenderMode.Client,
headers: {
'Cache-Control': 'private, no-store',
},
},
{
path: 'profile/public',
renderMode: RenderMode.Server,
headers: {
'Cache-Control': 'public, max-age=300',
},
},
{
path: '**',
renderMode: RenderMode.Server,
headers: {
'Cache-Control': 'public, max-age=300',
},
},
];
The /profile component reads a benign request-derived marker through the SSR REQUEST token.
Steps to reproduce
Request the normal client-only route:
curl -i \
-H 'Cookie: session=PRIVATE_VALUE' \
http://localhost:4000/profile
The initial HTML does not contain the request-derived value.
Request either crafted path:
curl -i \
-H 'Cookie: session=PRIVATE_VALUE' \
'http://localhost:4000/profile;'
curl -i \
-H 'Cookie: session=PRIVATE_VALUE' \
http://localhost:4000/profile//public
Actual behavior
The crafted requests can:
- render the
/profile component on the server;
- expose request-derived data in the initial HTML;
- apply
Cache-Control: public metadata belonging to another server route.
Expected behavior
The route used to select renderMode, status, and response headers must always correspond to the route whose body is rendered.
A route configured as RenderMode.Client should not be server-rendered through an alternative URL representation.
Your Environment
Anything else relevant?
This was previously reported at https://issuetracker.google.com/u/1/issues/518988455
Description
Angular SSR can select server-route metadata from one route while Angular Router renders a different route when the request URL contains certain ambiguous path forms.
Example:
In both cases, a route configured as
RenderMode.Clientcan be unexpectedly rendered on the server while inheriting public cache headers from anotherServerRoute.Minimal Reproduction
Minimal configuration
The
/profilecomponent reads a benign request-derived marker through the SSRREQUESTtoken.Steps to reproduce
Request the normal client-only route:
curl -i \ -H 'Cookie: session=PRIVATE_VALUE' \ http://localhost:4000/profileThe initial HTML does not contain the request-derived value.
Request either crafted path:
curl -i \ -H 'Cookie: session=PRIVATE_VALUE' \ http://localhost:4000/profile//publicActual behavior
The crafted requests can:
/profilecomponent on the server;Cache-Control: publicmetadata belonging to another server route.Expected behavior
The route used to select
renderMode, status, and response headers must always correspond to the route whose body is rendered.A route configured as
RenderMode.Clientshould not be server-rendered through an alternative URL representation.Your Environment
Anything else relevant?
This was previously reported at https://issuetracker.google.com/u/1/issues/518988455