Skip to content

Commit 4ffcaf9

Browse files
committed
fix(@angular/ssr): ensure public directory containment in CommonEngine
Ensure that paths resolved in `retrieveSSGPage` strictly remain within the configured `publicPath` by checking `relative()` containment before evaluating the static file. Previously, a string `startsWith()` check was used, which could match sibling directories that share the same name prefix as `publicPath`.
1 parent 4d3b5b7 commit 4ffcaf9

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

packages/angular/ssr/node/src/common-engine/common-engine.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ApplicationRef, StaticProvider, Type } from '@angular/core';
1010
import { BootstrapContext } from '@angular/platform-browser';
1111
import { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';
1212
import * as fs from 'node:fs';
13-
import { dirname, join, normalize, resolve } from 'node:path';
13+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
1414
import { URL } from 'node:url';
1515
import { validateUrl } from '../../../src/utils/validation';
1616
import { getAllowedHostsFromEnv } from '../environment-options';
@@ -155,16 +155,16 @@ export class CommonEngine {
155155
// See: https://portswigger.net/web-security/file-path-traversal
156156
const pagePath = join(publicPath, pathname, 'index.html');
157157

158+
const relativePath = relative(publicPath, pagePath);
159+
if (relativePath.startsWith('..') || isAbsolute(relativePath)) {
160+
return undefined;
161+
}
162+
158163
if (this.pageIsSSG.get(pagePath)) {
159164
// Serve pre-rendered page.
160165
return fs.promises.readFile(pagePath, 'utf-8');
161166
}
162167

163-
if (!pagePath.startsWith(normalize(publicPath))) {
164-
// Potential path traversal detected.
165-
return undefined;
166-
}
167-
168168
if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) {
169169
// View matches with prerender path or file does not exist.
170170
return undefined;

0 commit comments

Comments
 (0)