scaffolder-backend: use a const reference to helpers in the SecureTemplater
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -113,4 +113,33 @@ describe('SecureTemplater', () => {
|
||||
['https://my-host.com/my-owner/my-repo'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not allow helpers to be rewritten', async () => {
|
||||
const templater = new SecureTemplater({
|
||||
parseRepoUrl: () => ({
|
||||
repo: 'my-repo',
|
||||
owner: 'my-owner',
|
||||
host: 'my-host.com',
|
||||
}),
|
||||
});
|
||||
await templater.initializeIfNeeded();
|
||||
|
||||
const ctx = {
|
||||
repoUrl: 'https://my-host.com/my-owner/my-repo',
|
||||
};
|
||||
expect(
|
||||
templater.render(
|
||||
'${{ ({}).constructor.constructor("parseRepoUrl = () => JSON.stringify(`inject`)")() }}',
|
||||
ctx,
|
||||
),
|
||||
).toBe('');
|
||||
|
||||
expect(templater.render('${{ repoUrl | parseRepoUrl | dump }}', ctx)).toBe(
|
||||
JSON.stringify({
|
||||
repo: 'my-repo',
|
||||
owner: 'my-owner',
|
||||
host: 'my-host.com',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,11 +45,13 @@ const { render, renderCompat } = (() => {
|
||||
compatEnv.addFilter('jsonify', compatEnv.getFilter('dump'));
|
||||
|
||||
if (typeof parseRepoUrl !== 'undefined') {
|
||||
const safeHelperRef = parseRepoUrl;
|
||||
|
||||
env.addFilter('parseRepoUrl', repoUrl => {
|
||||
return JSON.parse(parseRepoUrl(repoUrl))
|
||||
return JSON.parse(safeHelperRef(repoUrl))
|
||||
});
|
||||
env.addFilter('projectSlug', repoUrl => {
|
||||
const { owner, repo } = JSON.parse(parseRepoUrl(repoUrl));
|
||||
const { owner, repo } = JSON.parse(safeHelperRef(repoUrl));
|
||||
return owner + '/' + repo;
|
||||
});
|
||||
}
|
||||
@@ -132,6 +134,9 @@ export class SecureTemplater {
|
||||
};
|
||||
}
|
||||
|
||||
// Note that helpers in the sandbox can be rewritten with a script injection.
|
||||
// In order to mitigate that each helper must be assigned to a constant variable
|
||||
// inside the closure that houses the nunjucks implementation.
|
||||
this.#vm = new VM({ timeout: 1000, sandbox });
|
||||
|
||||
const nunjucksSource = await fs.readFile(
|
||||
|
||||
Reference in New Issue
Block a user