Skip to content

Commit 678fe77

Browse files
committed
fix(core): Sandbox HTML binary files in viewing mode
1 parent 6783dcb commit 678fe77

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

packages/cli/src/controllers/__tests__/binary-data.controller.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,36 @@ describe('BinaryDataController', () => {
107107
);
108108
});
109109

110+
it('should set Content-Security-Policy for HTML in view mode', async () => {
111+
request.query = {
112+
id: 'filesystem:123',
113+
action: 'view',
114+
fileName: 'test.html',
115+
mimeType: 'text/html',
116+
};
117+
118+
binaryDataService.getAsStream.mockResolvedValue(mock());
119+
120+
await controller.get(request, response);
121+
122+
expect(response.header).toHaveBeenCalledWith('Content-Security-Policy', 'sandbox');
123+
});
124+
125+
it('should not set Content-Security-Policy for HTML in download mode', async () => {
126+
request.query = {
127+
id: 'filesystem:123',
128+
action: 'download',
129+
fileName: 'test.html',
130+
mimeType: 'text/html',
131+
};
132+
133+
binaryDataService.getAsStream.mockResolvedValue(mock());
134+
135+
await controller.get(request, response);
136+
137+
expect(response.header).not.toHaveBeenCalledWith('Content-Security-Policy', 'sandbox');
138+
});
139+
110140
it('should return the file stream on success', async () => {
111141
request.query = { id: 'filesystem:123', action: 'view' };
112142

packages/cli/src/controllers/binary-data.controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ export class BinaryDataController {
3838
} catch {}
3939
}
4040

41-
if (mimeType) res.setHeader('Content-Type', mimeType);
41+
if (mimeType) {
42+
res.setHeader('Content-Type', mimeType);
43+
44+
// Sandbox html files when viewed in a browser
45+
if (mimeType === 'text/html' && action === 'view') {
46+
res.header('Content-Security-Policy', 'sandbox');
47+
}
48+
}
4249

4350
if (action === 'download' && fileName) {
4451
const encodedFilename = encodeURIComponent(fileName);
@@ -47,7 +54,7 @@ export class BinaryDataController {
4754

4855
return await this.binaryDataService.getAsStream(binaryDataId);
4956
} catch (error) {
50-
if (error instanceof FileNotFoundError) return res.writeHead(404).end();
57+
if (error instanceof FileNotFoundError) return res.status(404).end();
5158
else throw error;
5259
}
5360
}

0 commit comments

Comments
 (0)