Skip to content

Commit 1529666

Browse files
committed
test(sandbox): resolve code-scanning findings on util's regression tests
Removes eval() from the format() parity test's literal-value comparisons (Semgrep javascript.browser.security.eval-detected) by building the real node:util comparison value directly instead of eval'ing the same source text used for the sandboxed side. Documents and suppresses the CodeQL js/bad-code-sanitization finding on runBody's plugin-source construction — body is always a fixed literal from within this file (never external input) and is expected to contain arbitrary JS syntax, including quote/backtick characters that a generic sanitizer would corrupt.
1 parent 65fe6ea commit 1529666

1 file changed

Lines changed: 28 additions & 19 deletions

File tree

packages/insomnia/src/templating/sandbox/util.regression.test.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,15 @@ const runFormat = (...args: unknown[]) =>
3838
// functions, -0/NaN/Infinity, circular references) — the literal is written directly into the
3939
// sandboxed source and compared against the identical literal evaluated by real node:util in the
4040
// same test, so no marshaling is required for the parity assertion to be meaningful.
41+
//
42+
// `body` is always a fixed string literal from a call site in this same test file (never data from
43+
// outside the process), and it's expected to contain arbitrary JS syntax including quote/backtick
44+
// characters (e.g. the quote-selection test below embeds a literal backtick) — escaping it would
45+
// corrupt those cases rather than add safety. The resulting source only ever runs inside the
46+
// disposable, isolated QuickJS sandbox this whole file is testing, never on the host.
4147
const runBody = (body: string) =>
4248
runTagInSandbox({
43-
pluginSource: `module.exports.templateTags = [{ name: 'r', run: function () { ${body} } }];`,
49+
pluginSource: `module.exports.templateTags = [{ name: 'r', run: function () { ${body} } }];`, // lgtm[js/bad-code-sanitization]
4450
tagName: 'r',
4551
envelope: envelope([]),
4652
bridge: noBridge,
@@ -75,27 +81,30 @@ describe('format — parity with node:util.format across JSON-transportable args
7581
});
7682

7783
describe('format — parity for values that cannot cross the JSON envelope', () => {
78-
const literalCases: [string, string][] = [
79-
['%s', '-0'],
80-
['%d', '-0'],
81-
['%i', '-0.5'],
82-
['%f', '"-0"'],
83-
['%s', 'NaN'],
84-
['%s', 'Infinity'],
85-
['%s', '-Infinity'],
86-
['%s', '10n'],
87-
['%d', '10n'],
88-
['%i', '10n'],
89-
['%f', '10n'],
90-
['%s', 'Symbol("s")'],
91-
['%d', 'Symbol("s")'],
92-
['%i', 'Symbol("s")'],
93-
['%f', 'Symbol("s")'],
84+
// `literal` is the exact source text embedded into the sandboxed run() body; `value` builds the
85+
// same value directly (no eval) for the real node:util comparison — both sides construct their
86+
// own copy of the value from scratch, so no marshaling occurs either way.
87+
const literalCases: { spec: string; literal: string; value: () => unknown }[] = [
88+
{ spec: '%s', literal: '-0', value: () => -0 },
89+
{ spec: '%d', literal: '-0', value: () => -0 },
90+
{ spec: '%i', literal: '-0.5', value: () => -0.5 },
91+
{ spec: '%f', literal: '"-0"', value: () => '-0' },
92+
{ spec: '%s', literal: 'NaN', value: () => Number.NaN },
93+
{ spec: '%s', literal: 'Infinity', value: () => Infinity },
94+
{ spec: '%s', literal: '-Infinity', value: () => -Infinity },
95+
{ spec: '%s', literal: '10n', value: () => 10n },
96+
{ spec: '%d', literal: '10n', value: () => 10n },
97+
{ spec: '%i', literal: '10n', value: () => 10n },
98+
{ spec: '%f', literal: '10n', value: () => 10n },
99+
{ spec: '%s', literal: 'Symbol("s")', value: () => Symbol('s') },
100+
{ spec: '%d', literal: 'Symbol("s")', value: () => Symbol('s') },
101+
{ spec: '%i', literal: 'Symbol("s")', value: () => Symbol('s') },
102+
{ spec: '%f', literal: 'Symbol("s")', value: () => Symbol('s') },
94103
];
95104

96-
it.each(literalCases)('format("%s", %s) matches node:util', async (spec, literal) => {
105+
it.each(literalCases)('format("%s", %s) matches node:util', async ({ spec, literal, value }) => {
97106
const actual = await runBody(`return require("util").format(${JSON.stringify(spec)}, ${literal});`);
98-
const expected = nodeFormat(spec, eval(literal));
107+
const expected = nodeFormat(spec, value());
99108
expect(actual).toBe(expected);
100109
});
101110

0 commit comments

Comments
 (0)