Files
renovate/tools/lint/rules/no-exec-shell-option.ts
Sebastian Poxhofer e44c9a2070 ci(oxlint): move custom oxlint rules to typescript and alternative API (#45337)
* ci: move custom oxlint rules to typescript and alternative API

* ci: add  to test sharding
2026-08-19 05:37:56 +00:00

43 lines
1.6 KiB
TypeScript

import { defineRule } from '@oxlint/plugins';
/**
* Flags a `shell` property set on an object literal (e.g. `ExecOptions`,
* `CommandWithOptions`) passed to `lib/util/exec`. Enabling the child
* process's shell reintroduces the injection risk that `exec()` is designed
* to avoid by running commands as an argv array - see the warning on
* `CommandWithOptions.shell` in `lib/util/exec/types.ts`.
*
* The implementation in `lib/util/exec/` itself is exempt, since it has to
* accept and plumb the option through. Call sites with a genuine, reviewed
* need for a shell (e.g. to run user-configured commands) should disable
* this rule inline with a justification instead of being silently exempted.
*/
export default defineRule({
meta: {
type: 'problem',
messages: {
noExecShellOption:
"Do not set 'shell' on exec options: it re-enables shell interpretation of the command, which can lead to command injection. Build the command as an argv array instead. If a shell is genuinely required, disable this rule inline with a justification.",
},
},
createOnce(context) {
return {
Property(node) {
if (node.parent.type !== 'ObjectExpression') {
return;
}
const { key } = node;
let name: string | undefined;
if (key.type === 'Identifier') {
name = key.name;
} else if (key.type === 'Literal' && typeof key.value === 'string') {
name = key.value;
}
if (name === 'shell') {
context.report({ node, messageId: 'noExecShellOption' });
}
},
};
},
});