@noctcore/eslint-plugin-security
v0.4.2
Published
Security ESLint rules: shell injection, path traversal, SSRF, open redirects, unsanitized HTML (XSS), timing-unsafe comparisons and server actions that bypass their action client.
Maintainers
Readme
@noctcore/eslint-plugin-security
Injection, path-traversal, SSRF, open-redirect, XSS and timing-attack rules that match high-precision syntactic sinks only; precision is the point.
Docs: noctcore.github.io/eslint-plugins/packages/security
Not a good fit for a project that wants broad taint tracking; this plugin trades recall for reports you can trust.
Requirements
- ESLint 9 or newer, flat config (
eslint.config.js) only. configs.recommendedregisters the plugin and sets rule severities, nothing else. It sets nofilesand no parser, so it applies to whatever files the rest of your config lints. To lint TypeScript, add afilespattern and@typescript-eslint/parser, as in the quick start.
Install
bun add -D @noctcore/eslint-plugin-security @typescript-eslint/parser # or npm i -D / pnpm add -DQuick start
// eslint.config.js
import tsParser from '@typescript-eslint/parser';
import security from '@noctcore/eslint-plugin-security';
export default [
{
...security.configs.recommended,
files: ['**/*.{ts,tsx}'],
languageOptions: { parser: tsParser },
},
// Optional: tune a preset rule's options.
{
files: ['**/*.{ts,tsx}'],
rules: {
'noctcore-security/no-shell-interpolation': ['error', { extraCallees: ['sh'] }],
},
},
];Opt-in rules
Three rules are exported but left out of recommended. Enable them with your own options:
// eslint.config.js
export default [
// ...the quick start's entries, then:
{
files: ['**/*.{ts,tsx}'],
languageOptions: { parser: tsParser },
rules: {
// High false-positive rate; enable where request objects reach the filesystem.
'noctcore-security/require-path-containment': ['error', { requestObjects: ['req', 'ctx'] }],
// Name the HTML producers you trust.
'noctcore-security/require-sanitized-html': ['error', { trustedSources: ['highlighter.codeToHtml()'] }],
// Needs your action-client names; with none configured it reports every exported action.
'noctcore-security/server-action-through-client': ['error', { actionClients: ['actionClient', 'authActionClient'] }],
},
},
];Rules
✅ on in recommended (error) · 🔘 opt-in: not on in recommended, enable it yourself · ⚙️ needs options · 🔧 --fix · 💡 suggestions · 💭 needs type info · ❌ deprecated
| Rule | Description | Preset | ⚙️ | 🔧 | 💡 | 💭 |
| --- | --- | :-: | :-: | :-: | :-: | :-: |
| no-shell-interpolation | A dynamically-interpolated command string must not flow into a shell runner (exec/execSync, or spawn/execFile with shell: true). Pass the program and arguments separately. | ✅ | | | | |
| no-timing-unsafe-compare | An HMAC digest or signature must not be compared with === / !== / == / != or Buffer#equals; use crypto.timingSafeEqual. | ✅ | | | | |
| no-user-controlled-fetch-url | Disallow HTTP requests whose origin is not fixed at authoring time: a runtime-controlled host enables SSRF. | ✅ | | | | |
| no-user-controlled-redirect | Disallow redirects whose target origin is not fixed at authoring time: a user-controlled target is an open redirect. | ✅ | | | | |
| require-path-containment | Request-shaped input (req.*) passed directly into path.join / path.resolve without a containment guard is a path-traversal sink. | 🔘 | | | | |
| require-sanitized-html | HTML reaching dangerouslySetInnerHTML, innerHTML, outerHTML or insertAdjacentHTML must be static markup or pass through a configured sanitizer. | 🔘 | | | | |
| server-action-through-client | In a 'use server' module every exported action must be built from a configured action client; a raw exported function bypasses input validation, error shaping and middleware. | 🔘 | ⚙️ | | | |
Severity policy
Every rule is error or off, never warn: a warning is a rule nobody obeys. See the
severity policy.
