no-dynamic-dependency-loading
ESLint rule documentation for no-dynamic-dependency-loading
📡 Live from GitHub — This documentation is fetched directly from no-dynamic-dependency-loading.md and cached for 6 hours.
Prevents runtime dependency injection with dynamic paths
This rule detects dynamically constructed paths in require() and import() statements
Severity: 🟠 HIGH
CWE: CWE-1104: Use of Unmaintained Third Party Components
OWASP Mobile: M2: Inadequate Supply Chain Security
Rule Details
This rule detects dynamically constructed paths in require() and import() statements. Dynamic dependency loading bypasses static analysis and package lock integrity checks, enabling dependency confusion and supply chain attacks.
Why This Matters
Dynamic imports create security vulnerabilities:
- Dependency confusion: Attackers publish malicious packages with similar names
- Supply chain attacks: Runtime code injection through compromised dynamic imports
- No integrity checks: Dynamic paths bypass lock file validation
- Code execution: Attackers can execute arbitrary code by controlling the import path
❌ Incorrect
// Dynamic require() with variable
const moduleName = req.query.module; // User-controlled!
const plugin = require(moduleName); // ❌ Code injection vulnerability
// Dynamic import() with template literal
const feature = userInput;
const module = await import(`./${feature}/index.js`); // ❌ Path traversal risk
// Dynamic require() from config
const config = JSON.parse(fs.readFileSync('config.json'));
const handler = require(config.handlerPath); // ❌ Config-based injection
// Conditional dynamic import
const libName = process.env.USE_ALT_LIB ? 'alt-lib' : 'main-lib';
const lib = require(libName); // ❌ Environment-controlled dependency✅ Correct
// Static imports (preferred)
import express from 'express'; // ✅ Static, lock file verified
import { Router } from './router'; // ✅ Static relative import
// Static require()
const fs = require('fs'); // ✅ Static
// Plugin system with allow list
const ALLOWED_PLUGINS = ['auth', 'logging', 'metrics'] as const;
type AllowedPlugin = (typeof ALLOWED_PLUGINS)[number];
function loadPlugin(name: string) {
if (!ALLOWED_PLUGINS.includes(name as AllowedPlugin)) {
throw new Error(`Plugin ${name} not in allow list`);
}
// Static switch instead of dynamic require
switch (name) {
case 'auth':
return require('./plugins/auth'); // ✅ Static path
case 'logging':
return require('./plugins/logging'); // ✅ Static path
case 'metrics':
return require('./plugins/metrics'); // ✅ Static path
default:
throw new Error('Invalid plugin');
}
}
// Code splitting with static imports
async function loadFeature(feature: 'admin' | 'user') {
if (feature === 'admin') {
return import('./features/admin'); // ✅ Static path
} else {
return import('./features/user'); // ✅ Static path
}
}Known False Negatives
The following patterns are not detected due to static analysis limitations:
Nested Dynamic Imports
Why: We only detect top-level dynamic require() and import(). Nested or indirect dynamic imports are not traced.
// ❌ NOT DETECTED - Indirect dynamic import
function loader(path: string) {
return import(path); // Dynamic import hidden in function
}
loader(userInput);Mitigation: Review all code paths that load dependencies. Enforce static imports via code review.
Eval-based Loading
Why: eval() and Function() constructor can dynamically load code, but are not import-specific.
// ❌ NOT DETECTED - Eval-based loading
eval(`const lib = require('${userInput}')`); // Use detect-eval-with-expression ruleMitigation: Enable detect-eval-with-expression rule. Never use eval() for imports.
Native Module Loading
Way: Native Node.js Module API dynamic loading is not detected.
// ❌ NOT DETECTED - Module._load
const Module = require('module');
Module._load(dynamicPath); // Low-level dynamic loadingMitigation: Avoid Module._load and other low-level APIs. Use static imports only.
⚙️ Configuration
This rule has no configuration options. It flags all non-literal arguments to require() and all non-literal import() sources.
🔗 Related Rules
require-dependency-integrity- SRI for CDN resourceslock-file- Enforce lock filesdetect-suspicious-dependencies- Dependency confusion