Security
Security-focused TypeScript source rules from eslint-plugin-security.
Reports likely security smells that warrant human review even if no exploit is statically provable: non-literal sinks for eval, file I/O, regex construction, child-process spawning, and cryptographic primitives.
Treat findings as hints, not proofs.
Source: eslint-plugin-security@4.0.0 (Apache-2.0, distribution requires propagating the upstream NOTICE attribution).
Rule index
Each rule name links to the detailed section below.
Examples come from the checked lint corpus or package-level rule tests when project layout matters.
security/detect-bidi-characters: Detect Trojan-Source bidi control characters hidden inside source.security/detect-buffer-noassert: Detect Buffer reads/writes called withnoAssert = true.security/detect-child-process: Detect any import ofchild_processand anyexec/execSynccall.security/detect-disable-mustache-escape: Detect assignments settingescapeMarkup = false(or the equivalent option on Handlebars/Mustache-style engines).security/detect-eval-with-expression: Detecteval(...)calls whose argument is not a string literal.security/detect-new-buffer: Detectnew Buffer(input)constructions with non-literal input, historical source of allocation-disclosure bugs.security/detect-no-csrf-before-method-override: Detect Express applications mountingcsrfmiddleware beforemethodOverride.security/detect-non-literal-fs-filename: Detectfscalls whose filename argument is not a string literal.security/detect-non-literal-regexp: Detectnew RegExp(...)construction.security/detect-non-literal-require: Detectrequire(...)calls whose specifier is computed at runtime.security/detect-object-injection: Detect dynamic bracket-access such asobj[req.body.x] = ....security/detect-possible-timing-attacks: Detect direct equality comparisons involving secret-like identifiers , usecrypto.timingSafeEqualinstead.security/detect-pseudoRandomBytes: Detectcrypto.pseudoRandomBytes, which produces values.security/detect-unsafe-regex: Detect regex literals with catastrophic backtracking potential (ReDoS).
Rules
security/detect-bidi-characters
Detect Trojan-Source bidi control characters (U+202A, U+202E, …) hidden inside source.
Example:
const safe = "user";
// reports: security/detect-bidi-characters (error)
const access = "user";security/detect-buffer-noassert
Detect Buffer reads/writes called with noAssert = true, which skips Node’s offset/length bounds checks.
The flag lets the offset slide past the buffer end and read unrelated memory, so production code should never set it.
Example:
const buffer = Buffer.alloc(8);
buffer.readDoubleLE(0, false);
// reports: security/detect-buffer-noassert (error)
buffer.readDoubleLE(0, true);security/detect-child-process
Detect any import of child_process and any exec/execSync call whose command argument is not a string literal.
Non-literal commands are the canonical shell-injection sink in Node services.
Example:
// reports: security/detect-child-process (error)
require("child_process").exec(command);security/detect-disable-mustache-escape
Detect assignments setting escapeMarkup = false (or the equivalent option on Handlebars/Mustache-style engines), which turns off HTML entity escaping in template output.
Result: an unguarded XSS sink for caller-controlled strings.
Example:
escapeMarkup = false;
// reports: security/detect-disable-mustache-escape (error)
view.escapeMarkup = false;security/detect-eval-with-expression
Detect eval(...) calls whose argument is not a string literal.
Any expression argument means caller-controlled data can reach a code-execution sink. The rule flags the call shape, not proven taint.
Example:
eval("alert()");
// reports: security/detect-eval-with-expression (error)
eval(userInput);security/detect-new-buffer
Detect new Buffer(input) constructions with non-literal input, historical source of allocation-disclosure bugs.
The three APIs that replaced it are offered as editor suggestions: Buffer.from, Buffer.alloc, and Buffer.allocUnsafe. None is applied automatically. Which one is correct depends on what the argument turns out to be, and this rule fires precisely when the argument is not a literal, so the source cannot say. Choosing for the author is how the constructor’s original hazard returns: Buffer.allocUnsafe applied to what was really a string hands back uninitialized heap memory.
The finding stays untagged even though Node deprecated its global constructor in DEP0005. This rule mirrors the upstream syntax-only match, which can also report a user-defined constructor named Buffer; a rule-level Deprecated tag would stamp that application constructor too.
Example:
new Buffer("safe");
// reports: security/detect-new-buffer (error)
new Buffer(input);security/detect-no-csrf-before-method-override
Detect Express applications mounting csrf middleware before methodOverride, which lets the CSRF token be bypassed.
Example:
express.methodOverride();
express.csrf();
// reports: security/detect-no-csrf-before-method-override (error)
express.methodOverride();security/detect-non-literal-fs-filename
Detect fs calls (readFile, writeFile, createReadStream, …) whose filename argument is not a string literal.
Dynamic filenames are the standard path-traversal sink; sanitise or allow-list before the call.
Example:
import fs from "fs";
fs.readFileSync("./safe.json");
// reports: security/detect-non-literal-fs-filename (error)
fs.readFileSync(filename);security/detect-non-literal-regexp
Detect new RegExp(...) construction whose pattern argument is not a string literal.
Caller-controlled patterns can both trigger catastrophic backtracking and let an attacker reshape the matcher to bypass intended validation.
Example:
new RegExp("^[a-z]+$");
// reports: security/detect-non-literal-regexp (error)
new RegExp(pattern);security/detect-non-literal-require
Detect require(...) calls whose specifier is computed at runtime.
A dynamic specifier lets caller-controlled data choose the module to load, bypassing any module allow-list on Node.
Example:
require("node:fs");
// reports: security/detect-non-literal-require (error)
require(moduleName);security/detect-object-injection
Detect dynamic bracket-access such as obj[req.body.x] = ..., which can let caller-controlled keys overwrite prototype-shaped properties or pull out unintended fields.
Fires on virtually any computed property access; expect a high false-positive rate in normal application code.
Example:
object["safe"];
// reports: security/detect-object-injection (error)
object[key];security/detect-possible-timing-attacks
Detect direct equality comparisons involving secret-like identifiers (if (token === expected)), use crypto.timingSafeEqual instead.
Example:
if (age === 5) {
}
// reports: security/detect-possible-timing-attacks (error)
if (password === "mypass") {
}security/detect-pseudoRandomBytes
Detect crypto.pseudoRandomBytes, which produces values that are not cryptographically secure.
Tokens, session ids, and key material must use crypto.randomBytes (or Web Crypto’s getRandomValues) instead.
Type-aware via the Checker, which resolves the object at the use site so an automatic rewrite never lands on a shadowed binding. Enabling this rule puts the whole run on the checker path; the diagnostic itself stays name-based and still reports without one.
Node deprecated the name in DEP0115 and the member name alone is rewritten to randomBytes, so the API is repaired whether it is called or passed around as a value. The rename is automatic when the source proves crypto is an import or require of Node’s crypto / node:crypto module. A name-only match gets the same edit as an editor suggestion instead, because a local application object can also be named crypto.
The rule stays untagged for that same reason. Diagnostic tags are rule-level, so Deprecated would also strike through a reported member on a user-defined crypto object.
Example:
crypto.randomBytes;
// reports: security/detect-pseudoRandomBytes (error)
crypto.pseudoRandomBytes;security/detect-unsafe-regex
Detect regex literals with catastrophic backtracking potential (ReDoS), typically nested or overlapping quantifiers over the same character set.
Matching caller-controlled input against such a pattern can block the event loop for seconds.
Example:
/^d+1337d+$/;
// reports: security/detect-unsafe-regex (error)
/(x+x+)+y/;