Semgrep javascript rules¶
rules_lgpl_javascript_database_rule-node-knex-sqli-injection¶
Summary:
Improper neutralization of special elements used in an SQL command (SQL Injection)
Severity: Critical
CWE: CWE-89
Description:
The application uses Knex query builder methods knex.raw() or whereRaw() with
untrusted user input directly concatenated into SQL queries. This bypasses Knex's
parameterized query mechanism and allows attackers to inject arbitrary SQL commands,
potentially leading to unauthorized data access, modification, or deletion. Raw SQL
methods are particularly dangerous because they disable the automatic escaping and
parameterization that makes Knex safe by default.
Remediation:
Consider using Knex's standard query builder methods like where(), insert(),
update(), and select() which automatically parameterize values and prevent SQL
injection. If raw SQL is absolutely necessary, use the positional binding syntax
with knex.raw('SELECT * FROM users WHERE id = ?', [userId]) or named bindings
with knex.raw('SELECT * FROM users WHERE id = :id', {id: userId}) to ensure
user input is safely parameterized. Recommended to avoid raw() and whereRaw()
entirely when possible, as the standard query builder provides type-safe, injection-
proof alternatives for nearly all SQL operations. For complex queries, consider
breaking them into smaller builder chain calls rather than resorting to raw SQL.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_database_rule-node-nosqli-injection¶
Summary:
Improper neutralization of special elements in data query logic
Severity: Critical
CWE: CWE-943
Description:
The application passes untrusted user input directly into MongoDB's findOne() query
method without proper sanitization. This allows attackers to inject MongoDB query
operators like $gt, $ne, $regex, or other special operators that can bypass
authentication checks, extract unauthorized data, or cause denial of service. NoSQL
injection occurs when user-controlled objects are used as query parameters, enabling
manipulation of query logic through specially crafted input.
Remediation:
Consider using the mongo-sanitize package to remove any keys starting with $
from user input before passing it to MongoDB queries. Install it with
npm install mongo-sanitize and apply it to all user-controlled data with
const clean = sanitize(req.body). Alternatively, validate input to ensure it
matches expected types - for example, explicitly cast IDs to strings with
String(userId) or validate that query values are primitives rather than objects.
Recommended to implement a strict schema validation layer using libraries like Joi
or express-validator to ensure user input conforms to expected data types and
formats before it reaches database queries. For production systems, consider using
Mongoose with strict schema definitions which provides additional protection against
unexpected query operator injection.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_database_rule-node-nosqli-js-injection¶
Summary:
Improper neutralization of special elements in data query logic
Severity: Critical
CWE: CWE-943
Description:
The application uses MongoDB's $where operator with untrusted user input, allowing
arbitrary JavaScript code execution within the database context. The $where operator
evaluates JavaScript expressions on the server side, and injecting user input directly
into these expressions enables attackers to execute malicious code, access sensitive
data, or cause denial of service. This is especially dangerous because it grants
server-side code execution capabilities rather than just query manipulation.
Remediation:
Consider completely avoiding the $where operator in MongoDB queries, as it is
inherently unsafe and has significant performance overhead. Replace $where-based
queries with MongoDB's native query operators like $gt, $lt, $regex, $and,
$or which provide the same functionality without JavaScript execution. For complex
conditions, use the aggregation pipeline with $expr operator which allows
field-to-field comparisons safely. Recommended to implement strict input validation
and use Mongoose schema methods or query builder patterns that prevent direct string
interpolation into queries. MongoDB deprecated $where in version 4.4 and newer
versions provide safer alternatives for all common use cases. If legacy code
absolutely requires $where, isolate it in a controlled function with extensive
input validation, though migration away from $where is strongly preferred.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_database_rule-node-sqli-injection¶
Summary:
Improper neutralization of special elements used in an SQL command (SQL Injection)
Severity: Critical
CWE: CWE-89
Description:
The application constructs SQL queries by concatenating untrusted user input using
string concatenation, template literals, or string addition with database driver
methods like query() from mysql, pg, mssql, oracledb, or sequelize. This allows
attackers to inject arbitrary SQL commands that can read, modify, or delete data,
bypass authentication, or execute administrative operations on the database. String
concatenation defeats all built-in protections provided by database drivers and makes
SQL injection trivial to exploit.
Remediation:
Consider using parameterized queries (also called prepared statements) which
separate SQL code from user data and prevent injection attacks. For mysql, use
connection.query('SELECT * FROM users WHERE id = ?', [userId]) with positional
parameters. For pg (PostgreSQL), use client.query('SELECT * FROM users WHERE id =
$1', [userId]) with numbered placeholders. For better type safety and developer
experience, recommended to use query builders like Knex.js or ORMs like Sequelize,
TypeORM, or Prisma which provide parameterized queries by default and reduce the
likelihood of SQL injection vulnerabilities. Avoid template literals and string
concatenation entirely when constructing SQL queries - even for table or column
names, use allowlisting to validate against a predefined set of safe values rather
than dynamic construction.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_database_rule-sequelize-weak-tls¶
Summary:
Selection of Less-Secure Algorithm During Negotiation (Algorithm Downgrade)
Severity: Critical
CWE: CWE-757
Description:
The Sequelize database connection configuration explicitly sets dialectOptions.ssl.
minVersion to TLSv1 or TLSv1.1 for MySQL, MariaDB, or PostgreSQL connections. Both
TLS 1.0 and TLS 1.1 are deprecated protocols with known cryptographic weaknesses
including vulnerability to POODLE and BEAST attacks, and they have been officially
prohibited by major compliance standards including PCI DSS since 2018. Using these
outdated protocol versions exposes database traffic to protocol downgrade attacks and
compromises the confidentiality and integrity of transmitted data.
Remediation:
Consider setting minVersion: 'TLSv1.3' in the dialectOptions.ssl configuration
to enforce the most secure TLS protocol available, which eliminates legacy cipher
suites and provides forward secrecy by default. If TLS 1.3 is not supported by your
database server, use minVersion: 'TLSv1.2' as the minimum acceptable standard -
TLS 1.2 is secure when properly configured and widely supported. Recommended to
also verify that your database server is configured to disable TLS 1.0 and 1.1
support entirely at the server level, as client-side enforcement alone may not
prevent downgrade attacks in all scenarios. For cloud database services, check your
provider's documentation to enable TLS 1.2+ enforcement server-side (AWS RDS,
Azure, and GCP all support this). Consider removing the minVersion setting
entirely to use Node.js defaults, which already enforce TLS 1.2+ in recent versions.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_electronjs_rule-electron-allow-http¶
Summary:
Cleartext Transmission of Sensitive Information
Severity: Critical
CWE: CWE-319
Description:
The BrowserWindow configuration sets webPreferences.allowRunningInsecureContent
to true, which permits the Electron application to load and execute content over
unencrypted HTTP connections. This makes the application vulnerable to
man-in-the-middle attacks where attackers can intercept, modify, or inject
malicious content into HTTP traffic, potentially compromising the entire
application and user data.
Remediation:
Consider removing the allowRunningInsecureContent: true setting from
webPreferences or explicitly setting it to false. Recommended to configure
your Electron application to only load resources over HTTPS by ensuring all
URLs use https:// protocol and serving all local content through secure
channels. If you need to load external content, implement a Content Security
Policy (CSP) that restricts resources to HTTPS origins only. For development
environments where HTTP is necessary, consider using environment-specific
configuration files rather than hardcoding insecure settings in production
code.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_electronjs_rule-electron-disable-websecurity¶
Summary:
Origin validation error
Severity: Critical
CWE: CWE-346
Description:
The BrowserWindow configuration sets webPreferences.webSecurity to false,
which disables Chromium's same-origin policy, cross-origin resource sharing (CORS)
restrictions, and Content Security Policy enforcement. This allows the Electron
application to load and execute code from any domain without security checks,
making it vulnerable to cross-site scripting (XSS), data exfiltration, and
arbitrary code execution attacks. Disabling web security effectively removes the
browser's fundamental security boundaries that protect users from malicious web
content.
Remediation:
Consider removing the webSecurity: false setting from webPreferences to
restore same-origin policy protections. If cross-origin requests are required,
recommended to configure proper CORS headers on the server side or use Electron's
webRequest API to modify response headers securely. For loading local files,
use the custom protocol registration feature (protocol.registerFileProtocol) with
appropriate privilege checks instead of disabling web security entirely. If you
need to bypass CORS for specific trusted domains during development, implement
environment-specific configurations and ensure web security is always enabled in
production builds.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_electronjs_rule-electron-experimental-features¶
Summary:
Least privilege violation
Severity: Critical
CWE: CWE-272
Description:
The BrowserWindow configuration sets webPreferences.experimentalFeatures to
true, which enables Chromium's experimental and potentially unstable features in
the Electron renderer process. These experimental features are not production-ready
and may contain security vulnerabilities, memory safety issues, or unexpected
behaviors that have not undergone thorough security review. Enabling such features
violates the principle of least privilege by exposing untested functionality that
could be exploited by malicious content.
Remediation:
Consider removing the experimentalFeatures: true setting from webPreferences
to use only stable, well-tested Chromium features. Recommended to evaluate
whether required functionality can be achieved using stable Electron APIs,
Node.js modules, or mature third-party libraries instead of experimental browser
features. If specific experimental features are absolutely necessary, carefully
review Electron and Chromium release notes to understand associated risks, and
implement compensating security controls such as strict sandboxing, Content
Security Policies, and input validation. Consider using feature flags to disable
experimental features in production while allowing them in development
environments.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_eval_rule-eval-require¶
Summary:
Use of incorrectly-resolved name or reference
Severity: Critical
CWE: CWE-706
Description:
The application passes untrusted user input from HTTP request parameters directly into
Node.js's require() function, creating a critical remote code execution vulnerability.
The require() function loads and executes JavaScript modules, and attackers can
manipulate the module path to load malicious packages, access internal modules not
intended for user access, or exploit path traversal to execute arbitrary code files from
the filesystem. This vulnerability allows complete server compromise, as attackers can
execute arbitrary JavaScript with full application privileges, access sensitive files,
steal environment variables, or establish persistent backdoors.
Remediation:
Never pass user input directly to require() - always validate against a strict
allowlist of permitted module names. Define an explicit array or Set containing only
the specific modules users should access, and reject any input not in this list. Use
exact string matching (e.g., allowedModules.includes(userInput)) rather than pattern
matching to prevent bypass attempts. Avoid using dynamic require() entirely when
possible - instead, load all necessary modules statically and use a switch statement or
object map to select the appropriate module based on validated user input. If you must
support plugin loading, implement a dedicated plugin directory with strict file naming
conventions and verify that resolved paths remain within the allowed directory using
path.resolve() and prefix checking. Consider using ES6 dynamic import() with
proper validation as it provides better security boundaries than CommonJS require().
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-sandbox-code-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) directly to the sandbox npm package's run() method. The sandbox
package executes JavaScript code in an isolated environment but does not provide secure
sandboxing - it uses Node.js's built-in vm module which has known sandbox escape
vulnerabilities. Attackers can craft malicious JavaScript payloads that break out of the
sandbox using prototype pollution, constructor manipulation, or other escape techniques
to execute arbitrary code on the Node.js server with full privileges. This creates a
critical remote code execution vulnerability.
Remediation:
Never execute user-provided code in Node.js applications, even in sandboxed environments.
The sandbox and vm modules cannot provide reliable security isolation against
determined attackers. Remove all functionality that executes dynamic user-provided
JavaScript code. If you need to support user-customizable logic, use a safe domain-specific
language (DSL) or expression evaluator with strict syntax limitations, such as
expr-eval or safe-eval-2 configured with minimal capabilities. Alternatively,
implement a predefined set of operations that users can configure through declarative
JSON configuration rather than executable code. For truly isolated code execution,
consider running user code in separate processes with strict resource limits using
containerization technologies like Docker with security profiles, though this requires
substantial security expertise to implement correctly.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-server-side-template-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input directly into the compile() function of
JavaScript template engines including Handlebars, Pug, Haml.js, EJS, Squirrelly, or Eta.
These template engines compile template strings into executable JavaScript functions, and
when user input is included in the template source code, attackers can inject malicious
template expressions that execute arbitrary JavaScript on the Node.js server. Template
injection allows attackers to access the full server-side context, execute system
commands, read sensitive files, access environment variables, or establish persistent
backdoors. This is a critical server-side template injection (SSTI) vulnerability that
leads to complete remote code execution.
Remediation:
Never pass user input directly into template engine compile() functions. Separate
template definitions from template data - store templates as static files or
pre-compiled strings, and pass user input only as data to the rendering context. Use
the template engine's rendering API (e.g., template.render(data) or ejs.render(templateString, data))
where user input is passed as the data object, not the template string. If you must
allow users to customize templates, use a safe templating system with auto-escaping
enabled and no code execution capabilities, or implement a template builder UI that
constructs templates from pre-approved components. Always enable auto-escaping in your
template engine to prevent XSS even when templates are safe from SSTI. Consider using
logic-less template engines like Mustache that have no code execution capabilities for
user-customizable templates.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm-code-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) to Node.js's built-in vm module functions including vm.runInContext(),
vm.runInNewContext(), vm.runInThisContext(), vm.compileFunction(), or the
vm.Script constructor. The vm module executes JavaScript code in isolated V8 contexts
but explicitly does not provide security isolation - it is designed only for running
trusted code in separate global scopes. Attackers can easily escape VM contexts using
prototype manipulation, constructor access, or other well-documented techniques to
execute arbitrary code on the Node.js server with full privileges. This creates a critical
remote code execution vulnerability.
Remediation:
Never use the vm module to execute untrusted code - it provides no security isolation
despite appearing to create separate contexts. As explicitly stated in Node.js
documentation, the vm module is not a security mechanism. Completely remove any
functionality that executes user-provided code. If you need dynamic behavior, implement
it using safe alternatives: use a switch statement or object map to select from
predefined safe operations, use JSON.parse() for data, or implement a restricted
domain-specific language (DSL) with a safe parser. For mathematical expressions,
consider libraries like expr-eval with strict configuration. If code execution is
absolutely unavoidable, isolate it in separate Docker containers or serverless functions
with no network access, read-only filesystems, and strict resource limits, though even
this requires substantial security expertise.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm-compilefunction-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) into the parsingContext option of Node.js's vm.compileFunction() method.
The vm.compileFunction() API compiles strings into JavaScript functions, and while the
code body might be trusted, providing user-controlled parsing context allows attackers to
inject malicious objects that become accessible during function compilation and execution.
The vm module does not provide security isolation, and attackers can manipulate the
parsing context to introduce prototype pollution, override built-in objects, or inject
code through context manipulation. This creates a code injection vulnerability that can
lead to remote code execution on the Node.js server.
Remediation:
Never pass user input to vm.compileFunction() or any vm module APIs. The vm
module explicitly does not provide security isolation and should never be used with
untrusted data. If you need to compile functions dynamically, ensure both the code and
the parsing context are completely under your application's control with no user
influence. Define the parsing context statically using only trusted objects. Better yet,
avoid dynamic function compilation entirely - use standard JavaScript functions defined
at compile time, or implement dynamic behavior through safe configuration (JSON objects
mapping user choices to predefined functions). For any scenario involving user-customizable
logic, redesign the architecture to use declarative configuration instead of executable
code, eliminating the need for vm module APIs completely.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm-runincontext-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) into the context object passed to Node.js's vm.runInContext() method. The
vm.runInContext() function executes code within a provided context object, and when
that context contains user-controlled data, attackers can inject malicious objects or
functions that become part of the execution environment. The vm module does not provide
security isolation and is only designed for separating global scopes of trusted code.
Attackers can manipulate the context to introduce prototype pollution, override built-in
objects and functions, or inject executable code disguised as data. This creates a critical
code injection vulnerability enabling remote code execution.
Remediation:
Never pass user input into vm.runInContext() context objects or use the vm module
with untrusted data. The vm module provides no security isolation despite creating
separate contexts. If you need to provide data to code execution, define the context
statically with only trusted objects and never incorporate user input. Better yet,
eliminate the need for vm.runInContext() entirely by redesigning your application to
avoid dynamic code execution. Use static functions and control flow (switch statements,
object maps) to implement dynamic behavior safely. For configuration, use JSON objects
that select from predefined safe operations. If you're using vm.runInContext() to
evaluate templates or expressions, replace it with dedicated safe libraries designed
for those specific purposes.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm-runinnewcontext-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) into the context object passed to Node.js's vm.runInNewContext() method.
The vm.runInNewContext() function creates a new V8 context and executes code within it,
but when the context object contains user-controlled data, attackers can inject malicious
objects, functions, or values that become part of the global scope during execution. The
vm module explicitly does not provide security isolation - it only separates global
scopes for organizational purposes. Attackers can exploit context injection to introduce
prototype pollution, override critical built-in functions, or inject executable code,
leading to remote code execution on the Node.js server.
Remediation:
Never use vm.runInNewContext() with user-controlled context objects or any untrusted
data. The vm module does not provide security sandboxing and should only be used with
completely trusted code and contexts. If you need to execute code with specific global
variables, define the context object statically with no user input. Ideally, remove all
usage of vm.runInNewContext() and redesign your application to avoid dynamic code
execution entirely. Implement dynamic behavior through safe mechanisms like switch
statements that select from predefined functions, or use configuration objects (JSON)
that control application logic without executing code. For template evaluation or
expression parsing, use dedicated libraries designed specifically for those purposes
with proper security controls.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm2-code-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) to the vm2 package's run() method or VMScript constructor. The vm2
library was designed to provide secure sandboxing for executing untrusted JavaScript
code, but has had numerous critical sandbox escape vulnerabilities discovered over the
years and is now deprecated and unmaintained. Attackers can exploit known or future
sandbox escape techniques to break out of the VM isolation and execute arbitrary code on
the Node.js server with full privileges. This creates a critical remote code execution
vulnerability, and the package should not be used for security purposes.
Remediation:
Immediately remove the vm2 package as it is deprecated, unmaintained, and has known
security vulnerabilities. Do not execute user-provided JavaScript code in Node.js
applications under any circumstances. If you need user-customizable logic, implement a
safe domain-specific language (DSL) with limited syntax and capabilities, or use
declarative JSON-based configuration that users can modify. For mathematical expressions,
consider libraries like expr-eval with strict whitelisting of allowed operations. If
code execution is absolutely required for your use case, isolate it in separate
containerized processes with strict resource limits, network isolation, read-only
filesystems, and no access to secrets or sensitive data. Even with isolation, avoid
executing untrusted code if any alternative design exists.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_eval_rule-vm2-context-injection¶
Summary:
Improper control of generation of code (Code Injection)
Severity: Critical
CWE: CWE-94
Description:
The application passes untrusted user input from HTTP request parameters (req.query,
req.body) into the sandbox context object when creating vm2 VM or NodeVM instances.
This allows attackers to inject malicious objects or functions into the sandbox's global
context, which can then be accessed and executed by code running in the VM. By controlling
the sandbox context, attackers can introduce prototype pollution, override built-in
functions, or inject malicious code that appears to be part of the trusted environment.
Combined with vm2's known sandbox escape vulnerabilities and deprecated status, this
creates a critical remote code execution risk where attackers can manipulate the execution
environment and escape the sandbox.
Remediation:
Immediately remove the vm2 package as it is deprecated and insecure. Never allow user
input to control the sandbox context or global scope of any code execution environment.
If you must provide a sandbox context, define it statically with only explicitly safe
objects and functions, never incorporating any user-provided data. Completely redesign
your architecture to avoid executing user-provided code. If users need customizable
behavior, implement it through declarative configuration (JSON schemas defining allowed
operations) rather than executable code. For plugin systems or extensibility, use a
well-defined API where plugins are installed by administrators, not end users, and are
vetted before deployment. Any architecture requiring untrusted code execution should be
reconsidered as it fundamentally cannot be made secure in Node.js.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_exec_rule-shelljs-os-command-exec¶
Summary:
Improper neutralization of special elements used in an OS command ('OS Command Injection')
Severity: Critical
CWE: CWE-78
Description:
User-controlled data is passed directly to the shelljs.exec() function, which
executes OS commands through a shell. This allows attackers to inject arbitrary
shell commands, potentially leading to complete system compromise. The shelljs
library provides shell access without proper input sanitization, making it
extremely dangerous when combined with untrusted input.
Remediation:
Consider avoiding the shelljs library entirely for operations involving user
input, as it provides direct shell access. Recommended to use the built-in
Node.js child_process.execFile() with an array of arguments instead, which
does not invoke a shell and treats arguments as discrete parameters. If
shelljs must be used, validate all user input against a strict allowlist and
never allow special shell characters like ;, |, &, $, or backticks.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_headers_rule-generic-header-injection¶
Summary:
Improper neutralization of HTTP headers for scripting syntax
Severity: Critical
CWE: CWE-644
Description:
The application uses untrusted user input from request properties (such as
req.query, req.params, or req.body) directly in HTTP response headers
via Express.js methods like res.set() or Node.js res.writeHead() without
proper validation or sanitization. This allows attackers to inject arbitrary
HTTP headers or perform response splitting attacks by including newline
characters (CRLF sequences) in the input. Header injection vulnerabilities
can lead to severe security issues including session fixation, cross-site
scripting through injected headers, cache poisoning, and authentication
bypass. Attackers can manipulate headers like Set-Cookie, Location, or
Content-Type to compromise application security and user data.
Remediation:
Consider validating and sanitizing all user input before using it in HTTP
headers. Remove or reject any input containing newline characters (\r, \n)
or other control characters that could be used for header injection. Use a
whitelist approach to validate that header values match expected patterns,
such as checking that redirect URLs are on an allowed domain list. For
Express.js applications, avoid directly using request data in headers - if
you must set dynamic headers, use strict validation like
value.replace(/[\\r\\n]/g, '') to strip dangerous characters. Consider
using security middleware like Helmet.js which provides protection against
common header-based attacks. For redirect scenarios, use a predefined map of
safe URLs rather than accepting arbitrary redirect targets. Never trust user
input for security-critical headers like Content-Type, Set-Cookie, or CORS
headers.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_jwt_rule-jwt-express-hardcoded¶
Summary:
Insufficiently protected credentials
Severity: Critical
CWE: CWE-522
Description:
Hardcoded JWT secret was detected in the secret configuration option passed
to the expressjwt middleware from the express-jwt package. Hardcoding
secrets like JWT signing keys poses a significant security risk because if
the source code ends up in a public repository, shared with contractors, or
compromised through a security breach, the secret is exposed. Attackers could
then use the secret to generate forged tokens with arbitrary claims and bypass
authentication entirely, gaining unauthorized access to protected routes in
your Express application.
Remediation:
Consider storing the JWT secret in an environment variable and accessing it
via process.env.JWT_SECRET in the expressjwt configuration object. This
keeps the secret out of version control and allows different secrets per
deployment environment. Recommended to use a secrets management service like
AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault for production
systems to securely store and tightly control access to JWT signing keys.
For local development, can use a .env file that is added to .gitignore
and load it with the dotenv package at application startup. Example:
expressjwt({ secret: process.env.JWT_SECRET, algorithms: ['HS256'] }).
Ensure the secret is cryptographically random and at least 256 bits (32
bytes) in length for HS256.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_jwt_rule-node-jwt-none-algorithm¶
Summary:
Use of a broken or risky cryptographic algorithm
Severity: Critical
CWE: CWE-327
Description:
The none algorithm is specified in calls to jwt.sign() or jwt.verify()
from the jsonwebtoken package. Using none as the algorithm means the JWT
is unsigned and provides no cryptographic integrity protection whatsoever.
Attackers can trivially modify the token payload to change user IDs, roles,
permissions, or any other claims, and the application will accept the modified
token as valid. This completely bypasses authentication and authorization
controls, allowing attackers to impersonate any user or escalate privileges by
simply editing the Base64-encoded payload.
Remediation:
Consider using HMAC-based algorithms like HS256, HS384, or HS512 for
symmetric signing with a shared secret, or RSA/ECDSA algorithms like
RS256, ES256 for asymmetric signing with public/private key pairs.
Recommended to use HS256 for most applications as it provides strong
security with good performance and simpler key management. For systems where
the token verifier should not have access to signing capabilities, can use
RS256 with RSA keys. Example: jwt.sign(payload, secret, { algorithm:
'HS256' }) and jwt.verify(token, secret, { algorithms: ['HS256'] }). When
calling jwt.verify(), always explicitly specify the allowed algorithms in
the algorithms array option to prevent algorithm confusion attacks. Never
allow the none algorithm in the algorithms array for verification.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_redirect_rule-express-open-redirect¶
Summary:
URL redirection to untrusted site 'open redirect'
Severity: Critical
CWE: CWE-601
Description:
The application passes untrusted user input to Express's res.redirect() method
without validation. This creates an open redirect vulnerability where attackers
can craft URLs that redirect victims to malicious sites while appearing to
originate from the legitimate application. Attackers exploit this to conduct
phishing attacks, steal credentials, or bypass security controls that trust
redirects from your domain.
Remediation:
Consider validating redirect URLs against an allowlist of permitted destinations
before passing to res.redirect(). Recommended to check if the URL is relative
(starts with / but not //) or matches approved domains using URL parsing.
Avoid directly using user input from query parameters or request bodies for
redirects. If dynamic redirects are necessary, implement strict validation:
parse the URL, verify the hostname against trusted domains, and reject any URLs
with unexpected protocols or patterns.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_redirect_rule-express-open-redirect2¶
Summary:
URL redirection to untrusted site 'open redirect'
Severity: Critical
CWE: CWE-601
Description:
Untrusted user input is used in Express response methods like res.location(),
res.redirect(), or HTTP headers (location, set(), setHeader()), which
can result in an open redirect vulnerability. Attackers can craft malicious URLs
that redirect victims to phishing sites or domains under attacker control to
steal credentials or session tokens.
Remediation:
Consider validating all redirect URLs against an allowlist of permitted
destinations before performing redirections. Recommended to define a set of
allowed URLs and use allowedUrls.includes(url) to verify the target is
trusted. Avoid using user input directly in res.redirect(), res.location(),
or Location headers. If user-provided URLs are necessary, ensure strict
validation and consider using relative paths within your application only.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_ssrf_rule-phantom-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: Critical
CWE: CWE-918
Description:
This rule detected user-controlled input being passed to PhantomJS browser
automation methods including page.open(), page.setContent(),
page.openUrl(), page.evaluateJavaScript(), and page.property('content')
without validation. When user input controls URLs loaded by headless browser
instances, Server-Side Request Forgery (SSRF) vulnerabilities arise that allow
attackers to force the server-side browser to access internal resources, cloud
metadata endpoints, or arbitrary web pages. This can expose internal APIs,
administrative interfaces, or enable attacks through the browser automation
context that bypass network restrictions.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against approved domains before passing URLs to PhantomJS methods. URL
validation should verify the scheme, hostname, and port to prevent bypasses.
Restrict allowed protocols to http:// and https:// only, explicitly
denying file://, javascript://, data://, and other dangerous schemes
that could enable local file access or code execution. For headless browser
scenarios, implement additional sandboxing by running PhantomJS in a
restricted network environment with egress filtering to block access to
internal IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
and cloud metadata endpoints (169.254.169.254). Consider using a server-side
mapping approach where user input provides keys that map to pre-approved URLs
rather than accepting arbitrary URLs directly.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_ssrf_rule-playwright-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: Critical
CWE: CWE-918
Description:
This rule detected user-controlled input being passed to Playwright browser
automation methods including page.goto(), page.setContent(),
page.evaluate(), page.evaluateHandle(), page.evaluateOnNewDocument(),
and context.addInitScript() without validation. When user input controls URLs
or scripts loaded by headless browser instances, Server-Side Request Forgery
(SSRF) vulnerabilities arise that allow attackers to force the server-side
browser to access internal resources, cloud metadata endpoints, or execute
arbitrary JavaScript. This can expose internal APIs, administrative interfaces,
or enable attacks through the browser automation context that bypass network
restrictions and security boundaries.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against approved domains before passing URLs to Playwright methods. URL
validation should verify the scheme, hostname, and port to prevent bypasses.
Restrict allowed protocols to http:// and https:// only, explicitly
denying file://, javascript://, data://, and other dangerous schemes
that could enable local file access or code execution. For headless browser
scenarios, implement additional sandboxing by configuring Playwright with
network request interception using page.route() to block requests to
internal IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
and cloud metadata endpoints (169.254.169.254). Consider running Playwright
in containerized environments with restricted network access and egress
filtering. Use a server-side mapping approach where user input provides keys
that map to pre-approved URLs rather than accepting arbitrary URLs directly.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_ssrf_rule-puppeteer-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: Critical
CWE: CWE-918
Description:
This rule detected user-controlled input being passed to Puppeteer browser
automation methods including page.goto(), page.setContent(),
page.evaluate(), page.evaluateHandle(), and page.evaluateOnNewDocument()
without validation. When user input controls URLs or scripts loaded by headless
browser instances, Server-Side Request Forgery (SSRF) vulnerabilities arise
that allow attackers to force the server-side browser to access internal
resources, cloud metadata endpoints, or execute arbitrary JavaScript. This can
expose internal APIs, administrative interfaces, or enable attacks through the
browser automation context that bypass network restrictions and security
boundaries.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against approved domains before passing URLs to Puppeteer methods. URL
validation should verify the scheme, hostname, and port to prevent bypasses.
Restrict allowed protocols to http:// and https:// only, explicitly
denying file://, javascript://, data://, and other dangerous schemes
that could enable local file access or code execution. For headless browser
scenarios, implement additional sandboxing by configuring Puppeteer with
network request interception using page.setRequestInterception(true) and
page.on('request') handlers to block requests to internal IP ranges
(127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and cloud metadata
endpoints (169.254.169.254). Consider running Puppeteer in containerized
environments with restricted network access and egress filtering. Use a
server-side mapping approach where user input provides keys that map to
pre-approved URLs rather than accepting arbitrary URLs directly.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_ssrf_rule-wkhtmltopdf-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: Critical
CWE: CWE-918
Description:
This rule detected user-controlled URLs being passed to the wkhtmltopdf()
function without validation. The wkhtmltopdf library uses a headless WebKit
engine to convert web pages to PDF documents, and when user input controls the
URL parameter, Server-Side Request Forgery (SSRF) vulnerabilities arise.
Attackers can exploit this to force the server to access internal resources,
cloud metadata endpoints (169.254.169.254), or scan internal network services.
This can expose internal APIs, administrative interfaces, sensitive files via
file:// URLs, or enable network mapping that bypasses firewall protections
and network segmentation.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against approved domains before passing URLs to wkhtmltopdf(). Use Node.js
URL parsing with new URL() to validate the scheme, hostname, and port, and
reject any URLs that don't match the allowlist. Restrict allowed protocols to
http:// and https:// only, explicitly denying file://, data://, and
other dangerous schemes that could enable local file access. Implement DNS
rebinding protection by resolving hostnames to IP addresses and blocking
private IP ranges (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
and cloud metadata addresses (169.254.169.254). Network-level defenses can
include running wkhtmltopdf in a sandboxed environment with egress filtering
rules to prevent connections to internal networks. Consider using a
server-side mapping approach where user input provides keys that map to
pre-configured safe URLs rather than accepting arbitrary URLs.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_xml_rule-node-entity-expansion¶
Summary:
Improper restriction of recursive entity references in DTDs (XML Entity Expansion)
Severity: Critical
CWE: CWE-776
Description:
The application passes user-controlled data to an expat.Parser() instance via
the write() method without proper entity processing controls. This exposes the
application to XML Entity Expansion attacks (also known as Billion Laughs attacks),
where maliciously crafted XML with recursive entity definitions can exhaust system
resources and cause denial of service.
Remediation:
Consider disabling external entity processing and DTD validation when parsing
untrusted XML. Recommended to configure the parser to reject documents containing
entity declarations using parser options. For the expat parser, avoid processing
user input directly or implement strict input validation before parsing. Consider
using safer XML parsing libraries that disable dangerous features by default, or
sanitize XML input to remove entity declarations before parsing.
OWASP:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_xml_rule-node-xpath-injection¶
Summary:
Improper neutralization of data within XPath expressions (XPath Injection)
Severity: Critical
CWE: CWE-643
Description:
The application passes untrusted user input directly to xpath.parse() without
proper validation or sanitization. This creates an XPath injection vulnerability
where attackers can craft malicious XPath expressions to access unauthorized data
from XML documents, bypass access controls, or extract sensitive information. The
taint analysis detected user input flowing from request objects into XPath parsing.
Remediation:
Consider using parameterized XPath queries if your XML library supports them to
separate query structure from user data. Recommended to validate user input
against a strict allowlist of permitted XPath expressions or query components
before parsing. Avoid string concatenation when building XPath queries. If dynamic
queries are necessary, implement input validation to reject special XPath
characters like /, [, ], ', and functions.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_xml_rule-node-xxe¶
Summary:
Improper restriction of XML external entity reference
Severity: Critical
CWE: CWE-611
Description:
The application uses libxmljs functions parseXmlString(), parseXml(),
SaxParser.parseString(), or SaxPushParser.push() to process user-controlled XML
data from HTTP request parameters without disabling external entity processing, making
it vulnerable to XML External Entity (XXE) attacks. When the libxmljs parser processes
untrusted XML input from request query parameters or request bodies with external
entity support enabled by default, attackers can exploit this to read arbitrary files
from the server filesystem, perform SSRF attacks against internal network services,
exfiltrate sensitive data through out-of-band channels, or cause Denial of Service
through billion laughs and entity expansion attacks.
Remediation:
Configure libxmljs to disable external entity resolution by passing { noent: false,
dtdload: false, dtdvalid: false } as the options parameter to parsing functions.
Setting noent: false prevents entity substitution, while dtdload: false and
dtdvalid: false disable DTD loading and validation entirely. This prevents XXE
attacks, entity expansion vulnerabilities, and billion laughs DoS attacks. Consider
migrating to actively maintained XML parsers like fast-xml-parser with safe default
configurations. Example: libxmljs.parseXml(xmlString, { noent: false, dtdload:
false, dtdvalid: false }); For node-expat users, consider using xmldom or
fast-xml-parser instead as they provide better security defaults. Additional
guidance at
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_xml_rule-xxe-expat¶
Summary:
Improper restriction of XML external entity reference
Severity: Critical
CWE: CWE-611
Description:
The application uses node-expat module's Parser() constructor and parse() or
write() methods to process user-controlled XML data from HTTP request parameters
without disabling external entity processing, making it vulnerable to XML External
Entity (XXE) attacks. When the expat parser processes untrusted XML input from request
query parameters or request bodies with external entity support enabled by default,
attackers can exploit this to read arbitrary files from the server, perform SSRF
attacks to internal network endpoints, exfiltrate sensitive data, or cause Denial of
Service through billion laughs and quadratic blowup entity expansion attacks.
Remediation:
The node-expat parser does not provide built-in options to disable external entity
processing, making it inherently unsafe for parsing untrusted XML input. Recommended
to migrate to safer XML parsing libraries like fast-xml-parser (which has secure
defaults), xmldom with proper configuration, or sax with external entity
resolution disabled. If you must use node-expat, implement strict input validation to
reject any XML containing DOCTYPE declarations or entity references before parsing.
Example with fast-xml-parser: const parser = new XMLParser({ processEntities: false,
allowBooleanAttributes: true }); const result = parser.parse(xmlString); Additional
guidance at
https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
- A4:2017-XML External Entities (XXE)
- A05:2021-Security Misconfiguration
rule-js-ts-child-process-exec-injection¶
Summary:
Command injection using exec() from child_process
Severity: High
CWE: CWE-78
Description:
User-controlled input is passed directly to the child_process.exec() function,
which executes commands through a system shell. This allows attackers to inject
arbitrary shell commands using metacharacters like ;, |, &, or $(),
potentially achieving remote code execution. The exec() function is inherently
dangerous because it spawns a shell to interpret the entire command string.
Remediation:
Consider using child_process.execFile() instead of exec(), which does not
spawn a shell and treats arguments as discrete parameters. Recommended to pass
the command and arguments as separate array elements like
execFile('command', [arg1, arg2]) to prevent shell injection. If exec()
must be used, validate all user input against a strict allowlist and never
concatenate user data into command strings.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_database_rule-sequelize-tls-cert-validation¶
Summary:
Improper certificate validation
Severity: High
CWE: CWE-295
Description:
The Sequelize database connection configuration sets dialectOptions.ssl.
rejectUnauthorized: false which disables TLS certificate validation for MySQL,
MariaDB, or PostgreSQL connections. This defeats the entire purpose of TLS encryption
because it allows attackers to present self-signed or invalid certificates during
man-in-the-middle (MITM) attacks without triggering any warnings. The connection will
appear encrypted but provides no assurance that the client is communicating with the
legitimate database server, making credentials and data vulnerable to interception.
Remediation:
Consider removing the rejectUnauthorized: false setting entirely and instead
configure proper certificate validation by providing the database server's CA
certificate with dialectOptions: { ssl: { ca: fs.readFileSync('/path/to/server-
ca.pem') } }. For cloud database providers, download the root certificate bundle
from your provider (AWS RDS, Azure Database, Google Cloud SQL all provide these)
and reference it in the SSL configuration. Recommended to use the require option
alongside proper CA configuration to enforce TLS and reject unauthorized
certificates. If using self-signed certificates in development, maintain separate
configuration files for development and production environments rather than
disabling validation globally. For local development, consider using properly
signed certificates from Let's Encrypt or setting up a local certificate authority
rather than disabling this critical security check.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_eval_rule-eval-nodejs¶
Summary:
Improper neutralization of directives in dynamically evaluated code ('Eval Injection')
Severity: High
CWE: CWE-95
Description:
The application passes user-controlled data from HTTP request parameters (req.query,
req.body) directly into dangerous code execution functions including eval(), the
Function() constructor, or string-based setTimeout()/setInterval() calls. These
JavaScript functions execute arbitrary code at runtime in the Node.js server context,
allowing attackers to execute system commands, access the filesystem, steal environment
variables containing secrets, or completely compromise the server. This is a critical
server-side injection vulnerability that can lead to full remote code execution.
Remediation:
Never pass user input directly to code execution functions in Node.js applications.
Completely remove calls to eval(), Function() constructor, and string-based timer
functions, replacing them with safer alternatives that don't execute arbitrary code.
For dynamic property access, use bracket notation combined with strict allowlisting
to validate keys. For data parsing, use JSON.parse() instead of eval(). For timer
callbacks, pass function references instead of strings. If you need to execute dynamic
logic based on user input, use a switch statement or object map to select from
predefined safe operations. Implement input validation at the application boundary,
rejecting any requests with unexpected parameters. Consider using static analysis tools
and linters configured to prohibit dangerous function usage throughout your codebase.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_jwt_rule-hardcoded-jwt-secret¶
Summary:
Use of hard-coded credentials
Severity: High
CWE: CWE-798
Description:
Hardcoded JWT secret or private key was detected in calls to jwt.sign() or
jwt.verify() from the jsonwebtoken package, or in SignJWT.sign() and
jwtVerify() methods from the jose package. Hardcoding secrets like JWT
signing keys poses a significant security risk because if the source code ends
up in a public repository or is compromised, the secret is exposed. Attackers
could then use the secret to generate forged tokens with arbitrary claims and
gain unauthorized access to the system.
Remediation:
Consider using environment variables to store the JWT secret and access it
via process.env.SECRET instead of hardcoding the value directly in source
code. This keeps the secret out of version control and allows different
secrets per deployment environment. For production systems, recommended to
use a secrets management service like AWS Secrets Manager, HashiCorp Vault,
or Azure Key Vault to securely store and tightly control access to JWT
signing keys. For local development, can use a .env file that is added to
.gitignore and load it with the dotenv package to access secrets from
process.env. Example: const token = jwt.sign(payload, process.env.SECRET,
{ algorithm: 'HS256' });
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_jwt_rule-jwt-exposed-credentials¶
Summary:
Insufficiently protected credentials
Severity: High
CWE: CWE-522
Description:
The application is storing a password in the JWT token payload passed to
jwt.sign() from the jsonwebtoken package or to SignJWT() constructor
from the jose package. Storing passwords in JWT token payloads is an
insecure practice that can lead to compromised credentials because JWT
payloads are only Base64-encoded, not encrypted. The password transmitted in
the JWT payload is therefore visible to anyone who intercepts the token or
has access to client-side storage where tokens are often kept. Attackers can
easily decode Base64 without any secret key and extract the password in plain
text.
Remediation:
Consider storing only non-sensitive user identifiers in JWT payloads, such
as user IDs, usernames, or email addresses that map to credentials stored
securely on the server. Recommended to never include passwords, API keys,
secret tokens, or other sensitive credentials in JWT claims. If you need to
transmit sensitive data, can use encrypted JWT (JWE) with the jose
package's CompactEncrypt class, though this adds complexity and it's still
better to avoid sending credentials in tokens altogether. For authentication
flows, the token itself serves as proof of identity after initial login, so
there's no need to include the password in subsequent requests. Example
secure payload: { user_id: 123, username: 'john_doe', role: 'admin' }
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_jwt_rule-jwt-exposed-data¶
Summary:
Insufficiently protected credentials
Severity: High
CWE: CWE-522
Description:
User-controlled input is passed directly to JWT.sign() method from the
jose package without validation or filtering. JWT payloads are only
Base64-encoded, not encrypted, so any data included in the token is visible
to anyone who can access it. If sensitive information like passwords, API
keys, social security numbers, or other confidential data is present in the
input object, it will be exposed through the JWT token payload and readable
by attackers who intercept or access the token.
Remediation:
Consider explicitly constructing the JWT payload with only the specific
non-sensitive fields needed, rather than passing entire user objects or
request parameters directly to JWT.sign(). Recommended to create an
allowlist of safe claims like user ID, username, email, and role, then copy
only those specific properties into the payload object. Can use object
destructuring to extract safe fields: const payload = { user_id: input.id,
username: input.username, role: input.role };. If you need to include more
dynamic data, consider validating and sanitizing the input first, and
explicitly exclude sensitive fields like passwords, tokens, or personal
information. For truly sensitive data that must be in a token, can use
encrypted JWT (JWE) with the jose package, though this adds complexity.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_jwt_rule-jwt-not-revoked¶
Summary:
Insufficiently protected credentials
Severity: High
CWE: CWE-522
Description:
No token revocation mechanism is configured in the expressjwt middleware
from the express-jwt package. Without the isRevoked callback function,
JWT tokens remain valid until they expire based on their exp claim, even if
they are compromised, leaked, or the user logs out. This means an attacker
who obtains a valid token can continue using it to access protected routes
until the token naturally expires, potentially hours or days later, and there
is no way to invalidate the token server-side.
Remediation:
Consider implementing the isRevoked callback function in the expressjwt
configuration to check if a token has been revoked before accepting it. The
callback should query a revocation list (such as a Redis set, database
table, or in-memory cache) containing revoked token IDs or JTI claims.
Recommended to store the token's jti (JWT ID) claim in your revocation
store when users log out or when tokens are compromised. The isRevoked
callback receives the request and token payload, and should return true if
the token is revoked. Example: expressjwt({ secret: 'secret', algorithms:
['HS256'], isRevoked: async (req, token) => { return await
redisClient.sIsMember('revoked_tokens', token.payload.jti); } }). Keep in
mind this adds a database/cache lookup to every authenticated request, so
performance considerations apply.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_ssrf_rule-node-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: High
CWE: CWE-918
Description:
This rule detected user-controlled URLs being passed to Node.js HTTP client
libraries including axios.get(), axios.post(), fetch(), http.get(),
http.request(), needle(), request(), urllib.request(),
superagent.get(), bent(), got.get(), net.connect(), and
socket.io-client.io(). When user input controls the destination URL of HTTP
requests without validation, Server-Side Request Forgery (SSRF) vulnerabilities
arise. SSRF allows attackers to force the server to make requests to internal
systems, cloud metadata endpoints (such as 169.254.169.254), or other
unauthorized destinations. This can expose internal APIs, databases,
administrative panels, or enable network scanning and pivoting attacks that
bypass firewall rules and network segmentation.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against a predefined set of safe domains before making HTTP requests. URL
validation should parse the full URL including scheme, hostname, and port to
prevent bypasses through URL parsing discrepancies. Deny dangerous protocols
like file://, gopher://, ftp://, and dict:// by only permitting
http:// and https://. Implement DNS rebinding protection by resolving
hostnames to IP addresses and rejecting private IP ranges (127.0.0.0/8,
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and cloud metadata addresses
(169.254.169.254). Network-level defenses can include configuring egress
filtering rules to restrict outbound connections from the application server,
or routing all HTTP client requests through a monitored proxy with request
filtering. When absolute URLs must be accepted, consider using a server-side
mapping approach where user input provides a key that maps to pre-configured
safe URLs rather than accepting URLs directly. For more information see OWASP: Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
OWASP:
- A1:2017-Injection
- A03:2021-Injection
javascript_buf_rule-buffer-noassert-read¶
Summary:
Out-of-bounds read
Severity: Medium
CWE: CWE-125
Description:
The application is using Node.js Buffer read methods such as readUInt8(),
readInt32LE(), readInt32BE(), readFloatLE(), or readDoubleLE() with the
noAssert parameter set to true. This disables bounds checking and could result
in reading beyond the end of the buffer, leading to out-of-bounds memory access.
When noAssert is set to true, these methods do not verify that the offset is
within the buffer bounds, allowing reads beyond the allocated memory region. This
can cause undefined behavior, application crashes, or potential security exploits
where attackers could read sensitive data from adjacent memory regions.
Remediation:
Consider removing the noAssert parameter or explicitly setting it to false
to enable automatic bounds checking on all Buffer read operations. The Node.js
runtime will throw a RangeError if the offset is out of bounds, preventing
out-of-bounds memory access. It is recommended to validate offsets before
performing read operations by checking that the offset plus the read size does
not exceed the buffer length (e.g., if (offset + 4 <= buffer.length)). For
performance-critical code where bounds checking overhead is a concern, manually
validate offsets once upfront rather than disabling bounds checking entirely.
Always wrap Buffer operations in try-catch blocks to gracefully handle any
RangeError exceptions that may occur during runtime.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
javascript_buf_rule-buffer-noassert-write¶
Summary:
Out-of-bounds write
Severity: Medium
CWE: CWE-787
Description:
The application is using Node.js Buffer write methods such as writeUInt8(),
writeInt32LE(), writeInt32BE(), writeFloatLE(), or writeDoubleLE() with
the noAssert parameter set to true. This disables bounds checking and could
result in writing beyond the end of the buffer, leading to memory corruption and
security vulnerabilities. When noAssert is set to true, these methods do not
verify that the offset is within the buffer bounds, allowing writes beyond the
allocated memory region. This can cause undefined behavior, corrupt adjacent data
structures, crash the application, or create exploitable conditions where
attackers could overwrite critical memory regions.
Remediation:
Consider removing the noAssert parameter or explicitly setting it to false
to enable automatic bounds checking on all Buffer write operations. The Node.js
runtime will throw a RangeError if the offset is out of bounds, preventing
memory corruption. It is recommended to validate offsets before performing write
operations by checking that the offset plus the write size does not exceed the
buffer length (e.g., if (offset + 4 <= buffer.length)). For
performance-critical code paths where bounds checking overhead is a concern,
consider manually validating offsets once upfront rather than disabling bounds
checking entirely. Always wrap Buffer write operations in try-catch blocks to
gracefully handle any RangeError exceptions that may occur during runtime.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
javascript_timing_rule-possible-timing-attacks¶
Summary:
Observable timing discrepancy
Severity: Medium
CWE: CWE-208
Description:
The application performs string comparisons using standard equality operators
(===, !==, ==, !=) against security-sensitive values like passwords,
tokens, API keys, or secrets. These operators perform character-by-character
comparison and exit early on the first mismatch, creating measurable timing
differences. Attackers can exploit these timing discrepancies through statistical
analysis to iteratively brute-force the expected value one character at a time.
Remediation:
Consider using crypto.timingSafeEqual() for comparing security-sensitive
strings to ensure constant-time comparison. This function compares buffers byte by
byte regardless of content, preventing timing-based side-channel attacks.
Recommended to convert both strings to Buffer objects with the same encoding
before comparison: crypto.timingSafeEqual(Buffer.from(input),
Buffer.from(expected)). This approach ensures equal execution time for all
comparisons.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-aes-ecb¶
Summary:
Use of a broken or risky cryptographic algorithm
Severity: Medium
CWE: CWE-327
Description:
The application uses crypto.createCipheriv() or crypto.createDecipheriv()
with AES in ECB (Electronic Codebook) mode, which is deterministic and reveals
patterns in encrypted data. ECB mode encrypts identical plaintext blocks into
identical ciphertext blocks, making it vulnerable to pattern analysis attacks.
This is particularly dangerous when encrypting structured data, images, or any
content with repeating patterns, as attackers can infer information about the
plaintext by analyzing the ciphertext structure.
Remediation:
Consider using AES with GCM (Galois/Counter Mode) or CBC (Cipher Block
Chaining) mode instead of ECB. GCM mode is recommended as it provides both
encryption and authentication, protecting against tampering attacks. Use
crypto.createCipheriv('aes-256-gcm', key, iv) for authenticated encryption.
If using CBC mode, ensure you generate a cryptographically random IV using
crypto.randomBytes(16) for each encryption operation and never reuse IVs.
For additional security with CBC, combine it with HMAC for authentication to
create an encrypt-then-MAC construction. The Node.js crypto module's GCM
implementation handles authentication tags automatically via the
cipher.getAuthTag() and decipher.setAuthTag() methods.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-aes-noiv¶
Summary:
Use of a broken or risky cryptographic algorithm
Severity: Medium
CWE: CWE-327
Description:
The application uses crypto.createCipheriv() with an empty string as the
initialization vector (IV) parameter, which results in a zero-value IV being
used for AES encryption. Using a static or zero IV defeats the purpose of the IV
and makes the encryption deterministic, allowing attackers to identify when the
same plaintext is encrypted multiple times. This vulnerability enables dictionary
attacks and pattern analysis, as identical plaintexts encrypted with the same key
will always produce identical ciphertexts, revealing information about the
encrypted data.
Remediation:
Always generate a cryptographically random IV using crypto.randomBytes(16)
for AES-128 or AES-192, or use a 12-byte IV with crypto.randomBytes(12) for
AES-GCM mode. The IV must be unique for each encryption operation with the same
key and should be generated using a cryptographically secure random number
generator. Store or transmit the IV alongside the ciphertext, as it does not
need to be kept secret but must not be reused. For AES-GCM mode, the combination
of key and IV must never be repeated, as IV reuse leads to catastrophic security
failures that can expose the authentication key. Consider using higher-level
encryption libraries like @noble/ciphers or the Web Crypto API's
crypto.subtle.encrypt() which handle IV generation automatically.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-insecure-random-generator¶
Summary:
Use of cryptographically weak pseudo-random number generator (PRNG)
Severity: Medium
CWE: CWE-338
Description:
The application uses cryptographically weak random number generators such as
crypto.pseudoRandomBytes() or Math.random() for security-sensitive
operations. The crypto.pseudoRandomBytes() function uses a non-cryptographic
PRNG that may be predictable, while Math.random() is explicitly designed for
general-purpose use and is completely unsuitable for cryptographic purposes.
Using these functions for generating session tokens, CSRF tokens, password reset
tokens, encryption keys, or other security-critical values allows attackers to
predict future outputs by observing previous values. This predictability can lead
to session hijacking, authentication bypass, or complete compromise of
cryptographic protections.
Remediation:
Replace all uses of crypto.pseudoRandomBytes() and Math.random() with
crypto.randomBytes() for any security-sensitive random number generation.
The crypto.randomBytes() function uses the operating system's
cryptographically secure random number generator (e.g., /dev/urandom on Linux,
CryptGenRandom on Windows). For generating random integers within a specific
range, use crypto.randomInt(min, max) which is available in Node.js 14.10.0
and later. When generating tokens or identifiers, consider using
crypto.randomUUID() for RFC 4122 compliant UUIDs, or encode random bytes
using base64url encoding with randomBytes(32).toString('base64url') for URL-
safe tokens. Note that crypto.pseudoRandomBytes() was deprecated in Node.js
v6.0.0 and should never be used in modern applications.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-md5¶
Summary:
Use of weak hash
Severity: Medium
CWE: CWE-328
Description:
The application uses MD5 hashing through various JavaScript APIs including
crypto.createHash('md5'), CryptoJS.MD5(), npm packages like md5,
blueimp-md5, js-md5, or libraries like node-forge and jshashes. MD5 is
cryptographically broken and vulnerable to collision attacks, where attackers
can generate two different inputs that produce identical hash outputs. Practical
collision attacks against MD5 have been demonstrated since 2004, and chosen-
prefix collision attacks are now feasible with modest computational resources.
Using MD5 for password hashing, digital signatures, certificate verification, or
data integrity checks allows attackers to forge authentication credentials,
create malicious files with legitimate signatures, or substitute trusted data
with malicious content.
Remediation:
Migrate to SHA-256 or SHA-3 for cryptographic hashing by using
crypto.createHash('sha256') or crypto.createHash('sha3-256') in the
Node.js crypto module. For password hashing specifically, use dedicated
password hashing functions like bcrypt (via the bcrypt npm package),
scrypt (via crypto.scrypt()), or Argon2 (via argon2 npm package) instead
of general-purpose hash functions. These algorithms include salt generation and
configurable work factors to resist brute-force attacks. If you need to
maintain compatibility with legacy systems using MD5 for non-security purposes
like checksums, clearly document that MD5 is only used for data integrity in
non-adversarial contexts, never for authentication or cryptographic purposes.
When migrating away from MD5 password hashes, implement a gradual migration
strategy that rehashes passwords with a secure algorithm during user login.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-sha1¶
Summary:
Use of weak hash
Severity: Medium
CWE: CWE-328
Description:
The application uses SHA-1 hashing through various JavaScript APIs including
crypto.createHash('sha1'), CryptoJS.SHA1(), npm packages like sha1 and
js-sha1, or libraries like node-forge, jshashes, hash.js, and jssha.
SHA-1 is cryptographically broken and vulnerable to collision attacks where
attackers can craft two different inputs that produce identical hash outputs.
The SHAttered attack demonstrated in 2017 showed practical SHA-1 collisions,
and subsequent research has made these attacks increasingly feasible. Using
SHA-1 for digital signatures, certificate validation, git commit verification,
or data integrity checks allows attackers to substitute malicious content while
maintaining the same hash, bypass authentication mechanisms, or forge
cryptographic signatures.
Remediation:
Replace SHA-1 with SHA-256 or SHA-3 using crypto.createHash('sha256') or
crypto.createHash('sha3-256') from Node.js's crypto module. For password
hashing, use dedicated algorithms like bcrypt, scrypt (via
crypto.scrypt()), or Argon2 (via the argon2 npm package) that include
salting and configurable work factors. For HMAC operations, migrate from
crypto.createHmac('sha1', key) to crypto.createHmac('sha256', key). If
integrating with legacy systems that require SHA-1 for non-cryptographic
purposes like git object hashing or legacy protocol compatibility, clearly
isolate and document these uses to prevent accidental use in security-critical
contexts. When replacing SHA-1 in existing systems, implement a versioned
migration strategy that can validate both old SHA-1 and new SHA-256 hashes
during the transition period.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-timing-attack¶
Summary:
Observable timing discrepancy
Severity: Medium
CWE: CWE-208
Description:
The application uses standard JavaScript equality operators (===, !==, ==,
!=) to compare sensitive values like passwords, tokens, secrets, API keys, or
authentication hashes. These operators perform short-circuit string comparisons
that return as soon as a difference is found, causing the comparison time to vary
based on how many characters match. An attacker can measure these timing
differences through repeated authentication attempts to gradually deduce the
correct value byte-by-byte. This timing side-channel attack is particularly
effective against string-based secrets and authentication tokens, where an
attacker with network access can make enough measurement attempts to extract the
entire secret through statistical timing analysis.
Remediation:
Use crypto.timingSafeEqual() for constant-time string comparisons when
validating passwords, tokens, or other secrets. This function compares two
Buffer or TypedArray objects in constant time regardless of their contents,
preventing timing attacks. Convert strings to buffers using
Buffer.from(string) before comparison. For example: crypto.timingSafeEqual(
Buffer.from(userToken), Buffer.from(expectedToken)). Note that both buffers
must have the same length or the function will throw an error, so ensure inputs
are normalized to the expected length. For password hashing specifically, use
bcrypt.compare() or argon2.verify() which include built-in constant-time
comparison. Alternative libraries like secure-compare npm package also provide
timing-safe comparison functions. Be aware that timing attack mitigation must be
applied consistently across all authentication code paths, as a single
vulnerable comparison can compromise the entire authentication system.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_crypto_rule-node-tls-reject¶
Summary:
Improper Certificate Validation
Severity: Medium
CWE: CWE-295
Description:
The application sets process.env.NODE_TLS_REJECT_UNAUTHORIZED to '0' or 0,
which disables TLS/SSL certificate validation for all HTTPS connections made by
Node.js. This environment variable instructs Node.js to accept any certificate
without verifying it against trusted Certificate Authorities, including self-
signed certificates, expired certificates, or certificates with incorrect
hostnames. Disabling certificate validation eliminates the authentication
component of TLS, making the application vulnerable to man-in-the-middle (MITM)
attacks where an attacker can intercept, read, and modify all encrypted traffic.
This setting affects all HTTPS requests globally within the Node.js process,
including those made by the https module, third-party HTTP clients like
axios or node-fetch, and any libraries that use TLS connections.
Remediation:
Never set NODE_TLS_REJECT_UNAUTHORIZED=0 in production environments. Remove
any code that sets this environment variable and rely on Node.js's default
secure behavior of validating certificates. For development or testing with
self-signed certificates, use proper certificate configuration instead of
disabling validation globally. Add custom CA certificates to the trust store
using the ca option in https.request() or tls.connect(), for example:
https.request({ ca: fs.readFileSync('custom-ca.pem') }). For development
environments, generate proper self-signed certificates with correct hostnames
and add them to your system's trust store. If you must connect to servers with
invalid certificates in specific cases, use the rejectUnauthorized: false
option on individual requests rather than disabling validation globally, and
clearly document why this exception is needed. Consider using tools like
mkcert to generate locally-trusted development certificates that don't
require disabling validation.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_crypto_rule-node-weak-crypto¶
Summary:
Use of a broken or risky cryptographic algorithm
Severity: Medium
CWE: CWE-327
Description:
The application uses crypto.createCipher() with DES (Data Encryption Standard)
encryption, which is cryptographically broken due to its small 56-bit key size.
DES keys can be brute-forced in hours using modern hardware, and specialized
cracking machines can break DES encryption in minutes. The algorithm was
officially deprecated by NIST in 2005 and should not be used for any security-
sensitive encryption. Additionally, crypto.createCipher() itself is deprecated
in favor of crypto.createCipheriv() because it uses an insecure key derivation
method. Using DES encryption provides a false sense of security while offering
minimal actual protection against determined attackers.
Remediation:
Replace DES with AES-256-GCM using crypto.createCipheriv() for authenticated
encryption. AES-256-GCM provides both confidentiality and authenticity with a
256-bit key size that is considered secure against brute-force attacks. Use
crypto.randomBytes(32) to generate encryption keys and crypto.randomBytes(12)
to generate nonces for GCM mode. Example: crypto.createCipheriv('aes-256-gcm',
key, iv). For compatibility with systems that require block cipher modes
without authentication, use AES-256-CBC with HMAC-SHA256 for encrypt-then-MAC
construction. Never use the deprecated crypto.createCipher() function, which
derives keys insecurely from passwords. If you need password-based encryption,
use crypto.scrypt() or crypto.pbkdf2() for key derivation before passing
the derived key to crypto.createCipheriv(). Migration from DES requires
re-encrypting all stored data, so plan for a gradual rollout with support for
both algorithms during the transition period.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_database_rule-sequelize-tls¶
Summary:
Cleartext transmission of sensitive information
Severity: Medium
CWE: CWE-319
Description:
The Sequelize database connection configuration for MySQL, MariaDB, PostgreSQL, or
Oracle does not enable TLS/SSL encryption in the dialectOptions.ssl settings. This
causes database credentials, queries, and result sets to be transmitted in cleartext
over the network, exposing them to interception by attackers performing man-in-the-
middle (MITM) attacks. Without transport encryption, any network observer can capture
sensitive data including authentication credentials and business-critical information.
Remediation:
Consider enabling TLS for all database connections by adding SSL configuration to
the Sequelize connection options. For PostgreSQL, add dialectOptions: { ssl: true
} to the configuration object. For MySQL and MariaDB, use dialectOptions: { ssl:
{ require: true } } or provide specific certificate options with { ssl: { ca:
fs.readFileSync('/path/to/ca.pem') } }. Recommended to configure the database
server to require TLS connections and reject unencrypted attempts to prevent
accidental downgrades. For cloud-hosted databases like AWS RDS, Azure Database, or
Google Cloud SQL, download the provider's root certificate and configure it
explicitly in the SSL options to ensure proper certificate validation. Production
deployments should enforce TLS 1.2 or higher and validate server certificates to
prevent MITM attacks completely.
OWASP:
- A3:2017-Sensitive Data Exposure
- A02:2021-Cryptographic Failures
rules_lgpl_javascript_dos_rule-layer7-object-dos¶
Summary:
Unchecked input for loop condition
Severity: Medium
CWE: CWE-606
Description:
The application is looping over user-controlled objects using methods like
Object.keys(), forEach(), map(), filter(), reduce(), or reduceRight(),
or iterating with for-loops based on user-controlled length properties. This can
lead to a layer 7 denial of service vulnerability when attackers send extremely
large objects or arrays that consume excessive CPU cycles or memory during iteration.
In Node.js applications, this can cause the entire application to become
unresponsive to other users' requests since JavaScript execution is single-threaded.
Remediation:
Consider implementing strict limits on the size of user-controlled objects and
arrays before iterating over them. Recommended to validate the length property
and reject requests that exceed reasonable thresholds (e.g., max 100 elements)
using middleware or early validation checks. For pagination scenarios, use
query parameter limits like ?limit=10&offset=0 with enforced maximum values.
Can also use streaming or chunked processing for large datasets instead of
loading entire objects into memory. Consider implementing rate limiting at the
API level using packages like express-rate-limit to prevent repeated abuse.
For complex object validation, libraries like joi or ajv can enforce schema
constraints including maximum array lengths and object property counts before
processing user input.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_dos_rule-regex-dos¶
Summary:
Incorrect regular expression
Severity: Medium
CWE: CWE-185
Description:
The application is using regex methods like .test() or .exec() to validate or
match against user-supplied input from request parameters, query strings, or body
properties. If the regular expression pattern contains vulnerable constructs that
cause catastrophic backtracking (such as nested quantifiers like (a+)+ or
overlapping alternations), attackers can craft input strings that cause Regular
Expression Denial of Service (ReDoS). This blocks Node.js's single-threaded event
loop and makes the application unresponsive to all users.
Remediation:
Consider analyzing all regular expression patterns for ReDoS vulnerabilities using
tools like redos-detector or safe-regex before deploying to production.
Recommended to replace vulnerable patterns with simpler alternatives that avoid
nested quantifiers and overlapping alternations. For complex validation scenarios,
consider migrating to the node-re2 package (npm install re2), which provides
linear-time regex matching guarantees and cannot be exploited for ReDoS attacks.
When using RE2, replace RegExp with RE2 constructor and note that some
JavaScript regex features like lookaheads are not supported. Can also implement
input length limits before regex processing (e.g., reject strings longer than
1000 characters) to reduce attack surface. For simple validation cases like email
or URL checking, consider using dedicated validation libraries like validator.js
instead of hand-written regex patterns.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_electronjs_rule-electron-blink-integration¶
Summary:
Least privilege violation
Severity: Medium
CWE: CWE-272
Description:
The BrowserWindow configuration enables Chromium Blink's experimental features
through webPreferences.enableBlinkFeatures. These experimental features are not
considered stable or production-ready, and may introduce unexpected security
vulnerabilities, memory corruption issues, or privilege escalation opportunities.
Enabling experimental features violates the principle of least privilege by
exposing untested browser capabilities to potentially untrusted content.
Remediation:
Consider removing the enableBlinkFeatures setting from webPreferences
entirely to use only stable, well-tested Chromium features. If specific
functionality is required, evaluate whether it can be achieved using stable
Electron APIs or Node.js modules instead of experimental browser features.
Recommended to thoroughly review Electron's security documentation and assess
whether the experimental features are truly necessary for your application's
functionality. If experimental features must be used, implement additional
security controls such as strict Content Security Policies, sandboxing, and
comprehensive input validation to mitigate potential risks.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_electronjs_rule-electron-context-isolation¶
Summary:
Improperly controlled modification of object prototype attributes ('Prototype Pollution')
Severity: Medium
CWE: CWE-1321
Description:
The BrowserWindow configuration sets webPreferences.contextIsolation to false,
which disables the security boundary between Electron's internal code and web
content. Without context isolation, JavaScript code running in web pages can
modify built-in JavaScript prototypes (Prototype Pollution), potentially affecting
Electron's internal functionality and leading to remote code execution if combined
with other vulnerabilities. This configuration allows untrusted web content to
directly access and manipulate the Node.js environment when nodeIntegration is
enabled.
Remediation:
Consider enabling context isolation by either removing the contextIsolation
setting (it defaults to true in Electron 12+) or explicitly setting it to true.
Recommended to use Electron's contextBridge API to expose only specific,
sanitized functions to renderer processes instead of allowing direct access to
Node.js APIs. The contextBridge provides a secure way to communicate between
isolated contexts while maintaining security boundaries. If migrating legacy code,
refactor preload scripts to use contextBridge.exposeInMainWorld() for controlled
API exposure. Context isolation is a critical security feature and should only be
disabled in exceptional circumstances with thorough security review.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_electronjs_rule-electron-nodejs-integration¶
Summary:
Least privilege violation
Severity: Medium
CWE: CWE-272
Description:
The BrowserWindow configuration sets webPreferences.nodeIntegration to true,
which exposes full Node.js APIs (including require(), fs, child_process) to
the renderer process and web content. If the application is vulnerable to
Cross-Site Scripting (XSS) or loads untrusted content, attackers can leverage
Node.js APIs to execute arbitrary system commands, access the filesystem, establish
network connections, or completely compromise the host system. This effectively
turns any XSS vulnerability into a remote code execution vulnerability.
Remediation:
Consider disabling Node.js integration by removing nodeIntegration: true or
explicitly setting it to false (the default since Electron 5). Recommended to use
Electron's IPC (Inter-Process Communication) mechanism with contextBridge and
preload scripts to expose only specific, sanitized functionality to renderer
processes. The contextBridge API allows you to selectively expose secure methods
using contextBridge.exposeInMainWorld() while maintaining context isolation. For
applications that require Node.js functionality, implement a security architecture
where sensitive operations are handled in the main process and communicated via
ipcRenderer/ipcMain with proper input validation and authorization checks. This
approach provides defense-in-depth against XSS exploitation.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-cookie-session-no-httponly¶
Summary:
Sensitive cookie without 'HttpOnly' flag
Severity: Medium
CWE: CWE-1004
Description:
The application explicitly sets httpOnly: false in the cookie-session or
express-session middleware cookie configuration, which allows client-side
JavaScript to access session cookies through document.cookie. This
significantly increases the risk of session hijacking through cross-site
scripting (XSS) attacks, as malicious scripts injected into the application
can steal session identifiers and send them to attacker-controlled servers.
The httpOnly flag is a critical defense-in-depth measure that prevents
JavaScript access to cookies even when XSS vulnerabilities exist in the
application.
Remediation:
Consider removing the httpOnly: false configuration or explicitly setting
httpOnly: true in your session middleware options. For example, use
session({ cookie: { httpOnly: true } }) when configuring the session. Note
that httpOnly is typically enabled by default in most session middleware, so
you may simply need to remove the explicit false setting. There are very
few legitimate use cases for allowing JavaScript access to session cookies,
and alternative approaches like separate authentication tokens should be
considered if client-side access to authentication state is needed. The
httpOnly flag provides protection even against sophisticated XSS attacks that
might bypass other security controls.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-cookie-session-no-samesite¶
Summary:
Sensitive cookie with improper SameSite attribute
Severity: Medium
CWE: CWE-1275
Description:
The application uses cookie-session or express-session middleware without
configuring the sameSite attribute to 'strict' or 'lax' in the cookie
options, which allows session cookies to be sent with cross-site requests
initiated by third-party websites. This missing protection makes the
application vulnerable to Cross-Site Request Forgery (CSRF) attacks where
malicious websites can trigger authenticated actions by leveraging the user's
active session. Without the sameSite attribute, browsers will send session
cookies with all requests regardless of origin, enabling attackers to perform
unauthorized operations on behalf of authenticated users.
Remediation:
Consider setting sameSite: 'strict' or sameSite: 'lax' in the session
middleware cookie configuration to prevent CSRF attacks. Use session({
cookie: { sameSite: 'strict' } }) for maximum protection, which prevents the
cookie from being sent with any cross-site request. For applications that
need to support incoming links from external sites (like email links or
social media), use sameSite: 'lax' instead, which allows cookies to be sent
with top-level navigation but blocks them for embedded requests like images
or iframes. In modern browsers, 'lax' is becoming the default, but explicit
configuration ensures consistent behavior. For APIs that need to accept
cross-origin requests, consider using token-based authentication instead of
cookie-based sessions.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-cookie-session-no-secure¶
Summary:
Sensitive cookie in HTTPS session without 'Secure' attribute
Severity: Medium
CWE: CWE-614
Description:
The application uses cookie-session or express-session middleware without
configuring the secure: true flag in the cookie options, which allows
session cookies to be transmitted over unencrypted HTTP connections. This
exposes session identifiers to network-based attackers who can intercept
traffic through man-in-the-middle attacks, potentially leading to session
hijacking and unauthorized account access. Without the secure flag, browsers
will send the session cookie over both HTTP and HTTPS connections.
Remediation:
Consider setting secure: true in the session middleware cookie
configuration to ensure session cookies are only transmitted over HTTPS
connections. For example, use session({ cookie: { secure: true } }) when
initializing the middleware. In production environments, this should always
be enabled, but note that it requires the application to be served over
HTTPS. For development environments using HTTP, you can conditionally set
this based on the environment, such as secure: process.env.NODE_ENV ===
'production'. Additionally, consider using the express-session package
with a secure session store like Redis or MongoDB rather than in-memory
storage for production applications.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-express-cors¶
Summary:
Origin validation error
Severity: Medium
CWE: CWE-346
Description:
The application sets the Access-Control-Allow-Origin response header to '*'
(wildcard) using Express.js methods like res.set(), res.header(), or
res.writeHead(), or enables wildcard CORS using app.options('*',
cors()). This disables the Same Origin Policy security mechanism, allowing
any website on the internet to make cross-origin requests to this application
and read the responses. This is particularly dangerous when the application
handles sensitive data or authentication, as malicious websites can make
requests on behalf of authenticated users and access their private
information. The wildcard origin bypasses the fundamental browser security
model designed to prevent unauthorized cross-origin data access.
Remediation:
Consider configuring CORS with a specific whitelist of allowed origins
instead of using the wildcard. For Express.js applications using the cors
middleware, use the origin option with an array or function, such as
cors({ origin: ['https://trusted-site.com', 'https://another-trusted.com']
}). For dynamic origin validation, use a function like cors({ origin:
(origin, callback) => { callback(null, allowedOrigins.includes(origin)) }
}). If you must support multiple origins, validate each origin against a
whitelist before setting the header. Never use wildcard CORS for APIs that
handle authentication or sensitive data. For public APIs that truly need
universal access, consider using API keys or other authentication mechanisms
instead of relying on CORS restrictions. Also ensure credentials are not
allowed when using broader CORS policies.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-generic-cors¶
Summary:
Origin validation error
Severity: Medium
CWE: CWE-346
Description:
The application uses app.options('*', cors()) to enable CORS preflight
responses for all routes with wildcard matching, which typically results in
setting Access-Control-Allow-Origin: * for OPTIONS requests. This
configuration disables Same Origin Policy protections across the entire
application, allowing any website to make cross-origin requests. While
OPTIONS requests themselves don't expose data, this pattern often indicates
an overly permissive CORS configuration that extends to actual data requests.
Wildcard CORS policies fundamentally undermine browser security mechanisms
designed to prevent unauthorized cross-origin access to sensitive resources.
Remediation:
Consider replacing the wildcard options handler with route-specific CORS
configurations that whitelist only trusted origins. Use the cors middleware
with specific origin configuration, such as app.options('/api/*', cors({
origin: 'https://trusted-domain.com' })) for specific route patterns. For
applications that need to support multiple trusted origins, use an array like
cors({ origin: ['https://site1.com', 'https://site2.com'] }) or implement
dynamic validation with an origin function. Remove the global app.options('*',
cors()) call and instead apply CORS middleware selectively to routes that
require cross-origin access. For public APIs, consider implementing API key
authentication rather than relying on CORS as a security control. Document
which origins are allowed and why in your codebase to prevent accidental
misconfigurations during updates.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-header-xss-generic¶
Summary:
Improperly implemented security check for standard
Severity: Medium
CWE: CWE-358
Description:
The application explicitly sets the X-XSS-Protection header to 0 using
Express.js methods like res.header(), res.set(), or res.writeHead(),
which disables the browser's built-in XSS filter. While modern browsers with
Content Security Policy support have deprecated this header in favor of CSP,
disabling XSS protection for older browsers removes an important
defense-in-depth layer against reflected cross-site scripting attacks. The
X-XSS-Protection header set to 0 explicitly tells browsers not to attempt
detecting and blocking XSS attacks, leaving users of older browsers more
vulnerable. This configuration is particularly problematic if the application
lacks a comprehensive Content Security Policy implementation.
Remediation:
Consider removing the explicit X-XSS-Protection: 0 header setting or
changing it to X-XSS-Protection: 1; mode=block to enable browser XSS
protection. For Express.js applications, you can use res.set('X-XSS-Protection',
'1; mode=block') or rely on Helmet.js middleware which sets secure defaults.
The best long-term solution is implementing a strict Content Security Policy
that prevents XSS attacks at the source, making the X-XSS-Protection header
redundant. If you're using Helmet, the default configuration enables
appropriate XSS protection. For modern applications, focus on implementing
CSP with directives like default-src 'self'; script-src 'self' to prevent
XSS attacks comprehensively. Only disable X-XSS-Protection if you have a
robust CSP implementation and have documented why backward compatibility with
older browsers is not required.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-header-xss-lusca¶
Summary:
Improperly implemented security check for standard
Severity: Medium
CWE: CWE-358
Description:
The application explicitly disables XSS protection in the Lusca security
middleware by using lusca.xssProtection(false) or lusca({ xssProtection:
false }), which prevents the X-XSS-Protection header from being set or
sets it to 0. Lusca is a security middleware that provides multiple
protection mechanisms, and disabling XSS protection removes an important
defense layer against reflected cross-site scripting attacks in older
browsers. While modern browsers have deprecated X-XSS-Protection in favor of
Content Security Policy, explicitly disabling it in the middleware
configuration leaves users of legacy browsers vulnerable. This configuration
suggests a deliberate choice to remove browser-level XSS protection without
necessarily having a comprehensive CSP alternative in place.
Remediation:
Consider removing the xssProtection: false setting from your Lusca
configuration to allow the default XSS protection header to be set. Lusca
enables X-XSS-Protection by default, so you can simply omit this option or
explicitly set lusca({ xssProtection: true }). If you're disabling it
because of conflicts with Content Security Policy, ensure you have a robust
CSP implementation before removing browser XSS filters. The best practice is
to use both Lusca's default XSS protection and implement a strict Content
Security Policy with directives like script-src 'self' to provide layered
defense. If using Helmet alongside Lusca, coordinate the middleware to avoid
conflicts while maintaining maximum protection. Consider that older browsers
still rely on X-XSS-Protection, so keeping it enabled provides backward
compatibility and defense-in-depth even when CSP is your primary XSS
prevention mechanism.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-helmet-feature-disabled¶
Summary:
Improperly implemented security check for standard
Severity: Medium
CWE: CWE-358
Description:
The application explicitly disables one or more security features in the
Helmet.js middleware by setting options like frameguard: false,
contentSecurityPolicy: false, hsts: false, noSniff: false, or
xssFilter: false. Helmet.js provides essential security headers by default,
and disabling these features removes critical protections against common web
vulnerabilities. Each disabled feature represents a specific attack vector:
frameguard prevents clickjacking, contentSecurityPolicy blocks XSS attacks,
hsts prevents SSL stripping, noSniff stops MIME type sniffing attacks, and
xssFilter enables browser XSS protection. Explicitly setting these to false
indicates a conscious decision to remove security controls, which is rarely
justified and significantly increases attack surface.
Remediation:
Consider removing the explicit false settings from your Helmet
configuration and allowing the default security headers to be set. If you
must disable specific features, document the business or technical
justification in code comments and restrict the disablement to specific
routes rather than globally. For Content Security Policy, if the default
policy is too strict, customize it with appropriate directives rather than
disabling it entirely, such as contentSecurityPolicy: { directives: {
defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"] } }. For
frameguard, use frameguard: { action: 'sameorigin' } if you need to allow
same-origin framing. Review each disabled feature and implement the security
control in the least permissive way possible. Consider using route-specific
Helmet configurations if certain routes have different security requirements.
Always prefer customizing policies over completely disabling security
features.
OWASP:
- A6:2017-Security Misconfiguration
- A05:2021-Security Misconfiguration
rules_lgpl_javascript_headers_rule-host-header-injection¶
Summary:
Use of less trusted source
Severity: Medium
CWE: CWE-348
Description:
The application uses the untrusted req.host or req.headers.host value
from the HTTP Host header to construct URLs, typically by concatenating it
with protocol strings like 'http://' or 'https://'. The Host header is
completely controlled by the attacker and can be manipulated to inject
malicious domains. This leads to web cache poisoning where cached responses
contain attacker-controlled URLs, password reset poisoning where reset links
point to attacker servers, and Server-Side Request Forgery (SSRF)
opportunities. These attacks are particularly severe when the generated URLs
are embedded in emails, stored in databases, or cached by CDNs, allowing
attackers to compromise users who never directly interacted with the
malicious request.
Remediation:
Consider using a hardcoded or configuration-based domain name instead of
relying on the Host header for URL generation. Define the application's
canonical domain in environment variables or configuration files, such as
const baseUrl = process.env.APP_BASE_URL || 'https://example.com' and use
this for constructing URLs. If you must use the Host header, implement strict
validation against a whitelist of allowed domains and reject any requests
with unexpected Host values. For Express.js applications, you can use
middleware to validate the Host header early in the request pipeline. When
deploying behind reverse proxies or load balancers, configure them to strip
or validate the Host header before it reaches your application. For password
reset and email scenarios, always use the configured application domain
rather than reflecting the Host header. Consider using req.protocol with a
configured domain instead of req.host for URL construction.
OWASP:
- A1:2017-Injection
- A03:2021-Injection
rules_lgpl_javascript_ssrf_rule-wkhtmltoimage-ssrf¶
Summary:
Server-side request forgery (SSRF)
Severity: Medium
CWE: CWE-918
Description:
This rule detected user-controlled URLs being passed to the
wkhtmltoimage.generate() function without validation. The wkhtmltoimage
library uses a headless WebKit engine to render web pages as images, and when
user input controls the URL parameter, Server-Side Request Forgery (SSRF)
vulnerabilities arise. Attackers can exploit this to force the server to
access internal resources, cloud metadata endpoints (169.254.169.254), or scan
internal network services. This can expose internal APIs, administrative
interfaces, sensitive files via file:// URLs, or enable network mapping that
bypasses firewall protections and network segmentation.
Remediation:
Consider implementing a strict URL allowlist that validates user input
against approved domains before passing URLs to wkhtmltoimage.generate().
Use Node.js URL parsing with new URL() to validate the scheme, hostname,
and port, and reject any URLs that don't match the allowlist. Restrict
allowed protocols to http:// and https:// only, explicitly denying
file://, data://, and other dangerous schemes that could enable local
file access. Implement DNS rebinding protection by resolving hostnames to IP
addresses and blocking private IP ranges (127.0.0.0/8, 10.0.0.0/8,
172.16.0.0/12, 192.168.0.0/16) and cloud metadata addresses
(169.254.169.254). Network-level defenses can include running wkhtmltoimage
in a sandboxed environment with egress filtering rules to prevent
connections to internal networks. Consider using a server-side mapping
approach where user input provides keys that map to pre-configured safe URLs
rather than accepting arbitrary URLs.
OWASP:
- A1:2017-Injection
- A10:2021-Server-Side Request Forgery
rules_lgpl_javascript_traversal_rule-admzip-path-overwrite¶
Summary:
Improper limitation of a pathname to a restricted directory ('Path Traversal')
Severity: Medium
CWE: CWE-22
Description:
This application extracts ZIP archives using the adm-zip package with fs.createWriteStream(), fs.writeFile(), or fs.writeFileSync() without properly sanitizing entry paths. Malicious ZIP archives can contain entries with path traversal sequences (e.g., ../../etc/passwd) that allow attackers to overwrite arbitrary files outside the intended extraction directory, potentially leading to code injection or system compromise.
Remediation:
Consider validating all entry paths before extraction by checking for path traversal sequences using entry.entryName.indexOf('..') or normalizing paths with path.basename(). Recommended to combine path.join() with path.basename() when constructing extraction paths, ensuring files are written only to the intended directory. For example, use fs.createWriteStream(path.join(extractDir, path.basename(entry.entryName))) instead of directly using entry.entryName. Additionally, consider using the adm-zip extractEntryTo() method which provides built-in path validation, or implement a whitelist of allowed file extensions to restrict extraction to safe file types only.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-express-lfr¶
Summary:
Relative path traversal
Severity: Medium
CWE: CWE-23
Description:
This application passes untrusted user input from req.body, req.params, req.query, req.cookies, or other request properties directly to the Express res.render() function. When using templating engines like Handlebars (hbs), Pug, or EJS, this enables local file read vulnerabilities where attackers can craft malicious input containing path traversal sequences (e.g., ../../etc/passwd) to access arbitrary files on the filesystem outside the intended template directory.
Remediation:
Consider using a whitelist approach where template names are mapped to hardcoded values rather than accepting user input directly. For example, create a mapping object like { home: 'index', profile: 'user-profile' } and use res.render(templateMap[req.query.page]) instead of res.render(req.query.page). Recommended to validate user input against a strict pattern (e.g., alphanumeric only) using regex before passing to render(). If dynamic template selection is required, normalize paths using path.basename() to strip directory traversal sequences, though whitelisting is the more secure approach. Additionally, configure your template engine to restrict template resolution to a specific directory and disable filesystem access outside that boundary when possible.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-express-lfr-warning¶
Summary:
Relative path traversal
Severity: Medium
CWE: CWE-23
Description:
This application uses Express with the res.render() function and passes untrusted user input from req.query, req.body, or other request sources as template parameters or view names. When combined with the Handlebars (hbs) templating engine, this pattern can enable local file read vulnerabilities where attackers exploit template resolution mechanisms to access files outside the intended views directory through path traversal sequences.
Remediation:
Consider implementing a strict whitelist of allowed template names and use an enumeration or mapping object to translate user input to safe template paths. For example, instead of res.render(req.query.view, data), use a lookup like const validViews = { home: 'index', about: 'about-us' }; and res.render(validViews[req.query.view] || 'default', data). Recommended to avoid passing user input as the view parameter entirely when possible. If dynamic template data is needed, ensure user input is only used within the data object passed as the second parameter to render(), never as the view path itself. Additionally, configure Express view engine settings to restrict template resolution to a specific directory using app.set('views', path.join(__dirname, 'views')) and consider using absolute paths.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-generic-path-traversal¶
Summary:
Relative path traversal
Severity: Medium
CWE: CWE-23
Description:
This application passes untrusted user input from request objects directly to Node.js filesystem functions including fs.readFile(), fs.readFileSync(), fs.readFileAsync(), or fs.createReadStream(). This enables directory traversal attacks where attackers craft malicious input containing path traversal sequences (e.g., ../../../../etc/passwd) to read arbitrary files outside the intended directory, potentially exposing sensitive configuration files, credentials, source code, or system files.
Remediation:
Consider implementing a whitelist of allowed filenames or file paths rather than accepting arbitrary user input. For example, use a mapping object to translate user input to safe paths, or validate that the requested file matches an expected pattern. Recommended to use path.basename() to strip any directory components from user input, combined with path.join() to construct the full path relative to a safe base directory. For instance, use fs.readFile(path.join(safeDir, path.basename(userInput))) to ensure files are only accessed within safeDir. Additionally, use path.resolve() to normalize the constructed path and verify it starts with your safe directory using startsWith() to prevent traversal attacks. Consider implementing file extension validation to restrict access to specific file types only.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-join-resolve-path-traversal¶
Summary:
Improper limitation of a pathname to a restricted directory ('Path Traversal')
Severity: Medium
CWE: CWE-22
Description:
This application constructs file paths using path.join() or path.resolve() with untrusted user input from req.body, req.query, or other request sources. While these path module functions normalize paths, they do not inherently prevent path traversal attacks. Attackers can supply input containing traversal sequences (e.g., ../../etc/passwd) that, when joined or resolved, may escape the intended directory and access arbitrary files on the filesystem when subsequently used with file operations.
Remediation:
Consider sanitizing user input before passing it to path.join() or path.resolve() by using path.basename() to strip any directory components. For example, use path.join(baseDir, path.basename(userInput)) instead of path.join(baseDir, userInput) to ensure only the filename portion is used. Recommended to implement a whitelist of allowed filenames or patterns and validate user input against this list before path construction. After constructing the path, verify that the resolved absolute path starts with your intended base directory using path.resolve() and startsWith() to catch any traversal attempts. For instance, const fullPath = path.resolve(baseDir, sanitizedInput); if (!fullPath.startsWith(baseDir)) throw error. Additionally, consider using path.normalize() carefully as it alone does not prevent traversal attacks.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-tar-path-overwrite¶
Summary:
Improper limitation of a pathname to a restricted directory ('Path Traversal')
Severity: Medium
CWE: CWE-22
Description:
This application extracts TAR archives using the tar-stream package with fs.createWriteStream(), fs.writeFile(), or fs.writeFileSync() within an 'entry' event handler without properly sanitizing entry paths. Malicious TAR archives can contain entries with path traversal sequences (e.g., ../../etc/cron.d/backdoor) that allow attackers to write arbitrary files outside the intended extraction directory, potentially leading to code injection, system compromise, or privilege escalation through overwriting critical system files.
Remediation:
Consider validating all entry paths in the 'entry' event handler by checking for path traversal sequences using header.name.indexOf('..') !== -1 before writing files. Recommended to normalize paths with path.basename() to strip directory components and combine with path.join() when constructing extraction paths. For example, use fs.createWriteStream(path.join(extractDir, path.basename(header.name))) instead of directly using header.name. Additionally, use path.resolve() to get the absolute path and verify it starts with your intended extraction directory before writing, rejecting any entries that escape the boundary. Consider implementing a whitelist of allowed file extensions and rejecting archives containing symbolic links or hardlinks that could be used for traversal attacks.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_traversal_rule-zip-path-overwrite¶
Summary:
Improper limitation of a pathname to a restricted directory ('Path Traversal')
Severity: Medium
CWE: CWE-22
Description:
This application extracts ZIP archives using the unzipper package with fs.createWriteStream(), fs.writeFile(), or fs.writeFileSync() within an 'entry' event handler without properly sanitizing entry paths. The pattern detects cases where entry.path is used directly for writing files without validation using path.basename() or checking for path traversal sequences with indexOf(). Malicious ZIP archives can contain entries with traversal sequences (e.g., ../../var/www/shell.php) that allow attackers to write arbitrary files outside the intended extraction directory, potentially leading to remote code execution or system compromise.
Remediation:
Consider sanitizing all entry paths before writing files by first validating with entry.path.indexOf('..') to detect traversal sequences and reject malicious entries. Recommended to use path.basename(entry.path) to extract only the filename component, then combine with a safe extraction directory using path.join(extractDir, path.basename(entry.path)). For preserving directory structure safely, normalize the path and verify it remains within bounds by using path.resolve() to get the absolute path and checking if it starts with your extraction directory. For example: const safePath = path.resolve(extractDir, entry.path); if (!safePath.startsWith(extractDir)) reject. Additionally, implement a whitelist of allowed file extensions and consider validating archive contents before extraction to prevent unrestricted file upload vulnerabilities.
OWASP:
- A5:2017-Broken Access Control
- A01:2021-Broken Access Control
rules_lgpl_javascript_headers_rule-cookie-session-default¶
Summary:
Insufficiently protected credentials
Severity: Info
CWE: CWE-522
Description:
The application uses cookie-session or express-session middleware with
the default cookie name (typically 'connect.sid' for express-session or
'session' for cookie-session), which provides unnecessary information to
potential attackers about the technology stack being used. This information
disclosure allows attackers to fingerprint the server and tailor attacks
specifically to known vulnerabilities in the detected frameworks or
middleware versions. While not directly exploitable, it reduces the effort
required for reconnaissance in targeted attacks.
Remediation:
Consider setting a custom cookie name using the name option in your session
middleware configuration, such as session({ name: 'sid' }) or another
non-descriptive identifier. Choose a generic name that doesn't reveal
information about your technology stack or session management approach. This
is a defense-in-depth measure that makes reconnaissance more difficult for
attackers. Note that changing the cookie name alone doesn't provide strong
security, so ensure other session security controls like secure,
httpOnly, and sameSite flags are properly configured. Some security
scanners and audits require custom cookie names as part of their compliance
criteria.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-cookie-session-no-domain¶
Summary:
Insufficiently protected credentials
Severity: Info
CWE: CWE-522
Description:
The application uses cookie-session or express-session middleware without
explicitly configuring the domain attribute in the cookie options, which
means the cookie will default to the exact domain that set it. While this
default behavior is often secure for single-domain applications, it can lead
to issues in multi-subdomain environments where session sharing or isolation
requirements aren't explicitly defined. Not setting the domain attribute may
cause unexpected behavior when applications span multiple subdomains or when
migrating between different domain configurations.
Remediation:
Consider explicitly setting the domain attribute in your session middleware
configuration based on your application's requirements. For single-domain
applications, you can set domain: 'example.com' to restrict cookies to that
specific domain. For applications that need to share sessions across
subdomains, use domain: '.example.com' (with a leading dot) to allow
cookies to be sent to all subdomains. Be cautious with subdomain sharing as
it can increase attack surface if one subdomain is compromised. For
applications that should not share sessions across subdomains, either omit
the domain attribute or set it explicitly to the current subdomain. Document
your domain configuration choice in the codebase to prevent security issues
during infrastructure changes.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-cookie-session-no-maxage¶
Summary:
Insufficient session expiration
Severity: Info
CWE: CWE-613
Description:
The application uses cookie-session or express-session middleware without
configuring the maxAge attribute in the cookie options, which results in
session cookies persisting as browser session cookies that are deleted when
the browser closes. While this default behavior provides some security by
limiting session lifetime, it can lead to poor user experience with frequent
re-authentication requirements and doesn't provide explicit control over
session duration. Without a defined maxAge, session lifetime management
relies entirely on browser behavior, which varies across different browsers
and user configurations.
Remediation:
Consider setting an appropriate maxAge value in milliseconds in your
session middleware configuration, such as session({ cookie: { maxAge: 3600000
} }) for a 1-hour session. The appropriate value depends on your
application's security requirements and user experience needs - shorter
durations (15-30 minutes) are more secure for sensitive applications, while
longer durations (hours or days) may be acceptable for lower-risk
applications. Remember that maxAge is specified in milliseconds, so use
constants or calculations like 24 * 60 * 60 * 1000 for clarity. For
high-security applications, consider implementing sliding session expiration
by updating the maxAge on each request. Also consider implementing both idle
timeout (maxAge) and absolute session timeout for defense in depth.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_headers_rule-cookie-session-no-path¶
Summary:
Insufficiently protected credentials
Severity: Info
CWE: CWE-522
Description:
The application uses cookie-session or express-session middleware without
explicitly configuring the path attribute in the cookie options, which
defaults to '/' and makes the cookie accessible to all paths on the domain.
While this default is often appropriate for applications where authentication
applies site-wide, it can lead to security issues in shared hosting
environments or when multiple applications run on different paths of the same
domain. Not explicitly setting the path attribute may result in session
cookies being unnecessarily sent with requests to unrelated application paths,
increasing exposure to cross-application attacks.
Remediation:
Consider explicitly setting the path attribute in your session middleware
configuration based on your application's deployment model. For most
applications, using path: '/' (the default) is appropriate and should be
explicitly set for clarity, such as session({ cookie: { path: '/' } }). For
applications mounted on specific path prefixes (e.g., '/app'), set path:
'/app' to restrict the cookie scope to only that path and its subpaths. This
prevents the cookie from being sent to other applications on the same domain.
Be careful when changing the path attribute in production, as it may cause
existing sessions to become inaccessible. Document your path configuration
choice, especially in environments where multiple applications share a domain
or when using reverse proxies with path-based routing.
OWASP:
- A2:2017-Broken Authentication
- A07:2021-Identification and Authentication Failures
rules_lgpl_javascript_xss_rule-xss-disable-mustache-escape¶
Summary:
None
Severity: Warning
Description:
The application sets escapeMarkup = false which disables HTML entity escaping in
template rendering libraries like Select2, Typeahead, or other UI components that
use this configuration option. When escapeMarkup is set to false, user-controlled
content is rendered directly into the DOM without converting dangerous characters
like <, >, and " into their HTML entity equivalents. This allows attackers to
inject malicious JavaScript through input fields, dropdown options, or autocomplete
suggestions. The vulnerability is particularly dangerous in search and autocomplete
interfaces where user input is immediately reflected back in the UI. XSS attacks
through these vectors can steal authentication tokens, hijack user sessions, or
perform actions on behalf of the victim.
Remediation:
Consider removing the escapeMarkup: false configuration and rely on the library's
default HTML escaping behavior which protects against XSS. If you need to render
formatted content in dropdown options or typeahead results, use a safer approach
like providing a custom template function that explicitly sanitizes user-controlled
portions while allowing safe HTML structure: templateResult: function(data) {
return $('<div>').text(data.userInput).html(); }. For libraries like Select2,
use the escapeMarkup function with DOMPurify to sanitize HTML while preserving
formatting: escapeMarkup: function(markup) { return DOMPurify.sanitize(markup); }.
Implement Content Security Policy (CSP) headers to limit XSS impact and validate
all user input on the server side before storing or displaying it.