eslint-plugin-secure-coding 2.4.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +149 -315
- package/package.json +1 -1
- package/src/index.d.ts +3 -12
- package/src/index.js +7 -2
- package/src/rules/detect-child-process/index.d.ts +18 -1
- package/src/rules/detect-child-process/index.js +5 -0
- package/src/rules/detect-eval-with-expression/index.d.ts +18 -1
- package/src/rules/detect-eval-with-expression/index.js +5 -0
- package/src/rules/detect-mixed-content/index.d.ts +6 -4
- package/src/rules/detect-mixed-content/index.js +7 -6
- package/src/rules/detect-non-literal-fs-filename/index.d.ts +18 -1
- package/src/rules/detect-non-literal-fs-filename/index.js +5 -0
- package/src/rules/detect-non-literal-regexp/index.d.ts +18 -1
- package/src/rules/detect-non-literal-regexp/index.js +5 -0
- package/src/rules/detect-object-injection/index.d.ts +23 -1
- package/src/rules/detect-object-injection/index.js +5 -0
- package/src/rules/detect-suspicious-dependencies/index.d.ts +6 -4
- package/src/rules/detect-suspicious-dependencies/index.js +7 -2
- package/src/rules/detect-weak-password-validation/index.d.ts +6 -2
- package/src/rules/detect-weak-password-validation/index.js +6 -1
- package/src/rules/no-allow-arbitrary-loads/index.d.ts +6 -4
- package/src/rules/no-allow-arbitrary-loads/index.js +7 -6
- package/src/rules/no-arbitrary-file-access/index.d.ts +6 -9
- package/src/rules/no-arbitrary-file-access/index.js +7 -2
- package/src/rules/no-buffer-overread/index.d.ts +10 -2
- package/src/rules/no-buffer-overread/index.js +5 -0
- package/src/rules/no-clickjacking/index.d.ts +25 -1
- package/src/rules/no-clickjacking/index.js +5 -0
- package/src/rules/no-client-side-auth-logic/index.d.ts +6 -2
- package/src/rules/no-client-side-auth-logic/index.js +6 -1
- package/src/rules/no-credentials-in-query-params/index.d.ts +6 -4
- package/src/rules/no-credentials-in-query-params/index.js +7 -2
- package/src/rules/no-data-in-temp-storage/index.d.ts +6 -2
- package/src/rules/no-data-in-temp-storage/index.js +6 -1
- package/src/rules/no-debug-code-in-production/index.d.ts +6 -4
- package/src/rules/no-debug-code-in-production/index.js +10 -7
- package/src/rules/no-directive-injection/index.d.ts +25 -1
- package/src/rules/no-directive-injection/index.js +5 -0
- package/src/rules/no-disabled-certificate-validation/index.d.ts +6 -2
- package/src/rules/no-disabled-certificate-validation/index.js +6 -1
- package/src/rules/no-dynamic-dependency-loading/index.d.ts +6 -4
- package/src/rules/no-dynamic-dependency-loading/index.js +10 -7
- package/src/rules/no-electron-security-issues/index.d.ts +25 -1
- package/src/rules/no-electron-security-issues/index.js +5 -0
- package/src/rules/no-exposed-debug-endpoints/index.d.ts +6 -2
- package/src/rules/no-exposed-debug-endpoints/index.js +6 -1
- package/src/rules/no-exposed-sensitive-data/index.d.ts +18 -1
- package/src/rules/no-exposed-sensitive-data/index.js +5 -0
- package/src/rules/no-format-string-injection/index.d.ts +26 -1
- package/src/rules/no-format-string-injection/index.js +5 -0
- package/src/rules/no-graphql-injection/index.d.ts +27 -1
- package/src/rules/no-graphql-injection/index.js +5 -0
- package/src/rules/no-hardcoded-credentials/index.d.ts +17 -1
- package/src/rules/no-hardcoded-credentials/index.js +5 -0
- package/src/rules/no-hardcoded-session-tokens/index.d.ts +6 -2
- package/src/rules/no-hardcoded-session-tokens/index.js +6 -1
- package/src/rules/no-http-urls/index.d.ts +7 -4
- package/src/rules/no-http-urls/index.js +7 -2
- package/src/rules/no-improper-sanitization/index.d.ts +25 -1
- package/src/rules/no-improper-sanitization/index.js +5 -0
- package/src/rules/no-improper-type-validation/index.d.ts +25 -1
- package/src/rules/no-improper-type-validation/index.js +5 -0
- package/src/rules/no-insecure-comparison/index.d.ts +18 -1
- package/src/rules/no-insecure-comparison/index.js +5 -0
- package/src/rules/no-insecure-redirects/index.d.ts +18 -1
- package/src/rules/no-insecure-redirects/index.js +5 -0
- package/src/rules/no-insecure-websocket/index.d.ts +6 -2
- package/src/rules/no-insecure-websocket/index.js +6 -1
- package/src/rules/no-ldap-injection/index.d.ts +28 -1
- package/src/rules/no-ldap-injection/index.js +5 -0
- package/src/rules/no-missing-authentication/index.d.ts +18 -1
- package/src/rules/no-missing-authentication/index.js +5 -0
- package/src/rules/no-missing-cors-check/index.d.ts +18 -1
- package/src/rules/no-missing-cors-check/index.js +5 -0
- package/src/rules/no-missing-csrf-protection/index.d.ts +18 -1
- package/src/rules/no-missing-csrf-protection/index.js +5 -0
- package/src/rules/no-missing-security-headers/index.d.ts +18 -1
- package/src/rules/no-missing-security-headers/index.js +5 -0
- package/src/rules/no-password-in-url/index.d.ts +6 -4
- package/src/rules/no-password-in-url/index.js +7 -6
- package/src/rules/no-permissive-cors/index.d.ts +6 -4
- package/src/rules/no-permissive-cors/index.js +22 -13
- package/src/rules/no-pii-in-logs/index.d.ts +6 -4
- package/src/rules/no-pii-in-logs/index.js +15 -12
- package/src/rules/no-privilege-escalation/index.d.ts +18 -1
- package/src/rules/no-privilege-escalation/index.js +5 -0
- package/src/rules/no-redos-vulnerable-regex/index.d.ts +20 -1
- package/src/rules/no-redos-vulnerable-regex/index.js +5 -0
- package/src/rules/no-sensitive-data-exposure/index.d.ts +18 -1
- package/src/rules/no-sensitive-data-exposure/index.js +5 -0
- package/src/rules/no-sensitive-data-in-analytics/index.d.ts +6 -4
- package/src/rules/no-sensitive-data-in-analytics/index.js +15 -11
- package/src/rules/no-sensitive-data-in-cache/index.d.ts +6 -4
- package/src/rules/no-sensitive-data-in-cache/index.js +7 -6
- package/src/rules/no-toctou-vulnerability/index.d.ts +18 -1
- package/src/rules/no-toctou-vulnerability/index.js +5 -0
- package/src/rules/no-tracking-without-consent/index.d.ts +6 -2
- package/src/rules/no-tracking-without-consent/index.js +6 -1
- package/src/rules/no-unchecked-loop-condition/index.d.ts +25 -1
- package/src/rules/no-unchecked-loop-condition/index.js +5 -0
- package/src/rules/no-unencrypted-transmission/index.d.ts +18 -1
- package/src/rules/no-unencrypted-transmission/index.js +5 -0
- package/src/rules/no-unescaped-url-parameter/index.d.ts +18 -1
- package/src/rules/no-unescaped-url-parameter/index.js +5 -0
- package/src/rules/no-unlimited-resource-allocation/index.d.ts +25 -1
- package/src/rules/no-unlimited-resource-allocation/index.js +5 -0
- package/src/rules/no-unsafe-deserialization/index.d.ts +29 -1
- package/src/rules/no-unsafe-deserialization/index.js +5 -0
- package/src/rules/no-unsafe-dynamic-require/index.d.ts +13 -1
- package/src/rules/no-unsafe-dynamic-require/index.js +5 -0
- package/src/rules/no-unsafe-regex-construction/index.d.ts +20 -1
- package/src/rules/no-unsafe-regex-construction/index.js +5 -0
- package/src/rules/no-unvalidated-deeplinks/index.d.ts +6 -2
- package/src/rules/no-unvalidated-deeplinks/index.js +6 -1
- package/src/rules/no-unvalidated-user-input/index.d.ts +18 -1
- package/src/rules/no-unvalidated-user-input/index.js +5 -0
- package/src/rules/no-verbose-error-messages/index.d.ts +6 -4
- package/src/rules/no-verbose-error-messages/index.js +7 -2
- package/src/rules/no-weak-password-recovery/index.d.ts +25 -1
- package/src/rules/no-weak-password-recovery/index.js +5 -0
- package/src/rules/no-xpath-injection/index.d.ts +28 -1
- package/src/rules/no-xpath-injection/index.js +5 -0
- package/src/rules/no-xxe-injection/index.d.ts +28 -1
- package/src/rules/no-xxe-injection/index.js +5 -0
- package/src/rules/no-zip-slip/index.d.ts +25 -1
- package/src/rules/no-zip-slip/index.js +5 -0
- package/src/rules/require-backend-authorization/index.d.ts +6 -2
- package/src/rules/require-backend-authorization/index.js +6 -1
- package/src/rules/require-code-minification/index.d.ts +6 -4
- package/src/rules/require-code-minification/index.js +7 -6
- package/src/rules/require-csp-headers/index.d.ts +6 -2
- package/src/rules/require-csp-headers/index.js +6 -1
- package/src/rules/require-data-minimization/index.d.ts +6 -4
- package/src/rules/require-data-minimization/index.js +9 -7
- package/src/rules/require-dependency-integrity/index.d.ts +6 -2
- package/src/rules/require-dependency-integrity/index.js +6 -1
- package/src/rules/require-https-only/index.d.ts +6 -4
- package/src/rules/require-https-only/index.js +24 -19
- package/src/rules/require-mime-type-validation/index.d.ts +6 -2
- package/src/rules/require-mime-type-validation/index.js +6 -1
- package/src/rules/require-network-timeout/index.d.ts +6 -4
- package/src/rules/require-network-timeout/index.js +18 -11
- package/src/rules/require-package-lock/index.d.ts +6 -4
- package/src/rules/require-package-lock/index.js +7 -6
- package/src/rules/require-secure-credential-storage/index.d.ts +6 -4
- package/src/rules/require-secure-credential-storage/index.js +12 -9
- package/src/rules/require-secure-defaults/index.d.ts +6 -4
- package/src/rules/require-secure-defaults/index.js +7 -6
- package/src/rules/require-secure-deletion/index.d.ts +6 -4
- package/src/rules/require-secure-deletion/index.js +7 -6
- package/src/rules/require-storage-encryption/index.d.ts +6 -4
- package/src/rules/require-storage-encryption/index.js +10 -7
- package/src/rules/require-url-validation/index.d.ts +6 -2
- package/src/rules/require-url-validation/index.js +6 -1
- package/src/types/index.d.ts +5 -0
- package/src/types/index.js +3 -12
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noInsecureComparison = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-insecure-redirects
|
|
8
|
+
* Detects open redirect vulnerabilities
|
|
9
|
+
* CWE-601: URL Redirection to Untrusted Site ('Open Redirect')
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/601.html
|
|
12
|
+
* @see https://owasp.org/www-community/vulnerabilities/Unvalidated_Redirects_and_Forwards
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'insecureRedirect' | 'whitelistDomains' | 'validateRedirect' | 'useRelativeUrl';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Ignore in test files. Default: true */
|
|
3
18
|
ignoreInTests?: boolean;
|
|
4
19
|
/** Allowed redirect domains. Default: [] */
|
|
5
20
|
allowedDomains?: string[];
|
|
6
21
|
}
|
|
7
|
-
|
|
22
|
+
type RuleOptions = [Options?];
|
|
23
|
+
export declare const noInsecureRedirects: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
24
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noInsecureRedirects = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
3
5
|
*/
|
|
4
6
|
export interface Options {
|
|
5
7
|
}
|
|
6
|
-
|
|
8
|
+
type RuleOptions = [Options?];
|
|
9
|
+
export declare const noInsecureWebsocket: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
export {};
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
4
6
|
*/
|
|
5
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
8
|
exports.noInsecureWebsocket = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* @fileoverview Require secure WebSocket connections (wss://)
|
|
11
|
+
*/
|
|
7
12
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
8
13
|
exports.noInsecureWebsocket = (0, eslint_devkit_1.createRule)({
|
|
9
14
|
name: 'no-insecure-websocket',
|
|
@@ -1,4 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-ldap-injection
|
|
8
|
+
* Detects LDAP injection vulnerabilities (CWE-90)
|
|
9
|
+
*
|
|
10
|
+
* LDAP injection occurs when user input is improperly inserted into LDAP
|
|
11
|
+
* queries, allowing attackers to:
|
|
12
|
+
* - Bypass authentication and authorization
|
|
13
|
+
* - Extract sensitive directory information
|
|
14
|
+
* - Perform unauthorized LDAP operations
|
|
15
|
+
* - Enumerate users through blind injection techniques
|
|
16
|
+
*
|
|
17
|
+
* False Positive Reduction:
|
|
18
|
+
* This rule uses security utilities to reduce false positives by detecting:
|
|
19
|
+
* - Safe LDAP libraries with built-in escaping
|
|
20
|
+
* - Input validation and sanitization functions
|
|
21
|
+
* - JSDoc annotations (@ldap-safe, @escaped)
|
|
22
|
+
* - Parameterized LDAP query construction
|
|
23
|
+
*/
|
|
24
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
1
25
|
import { type SecurityRuleOptions } from '@interlace/eslint-devkit';
|
|
26
|
+
type MessageIds = 'ldapInjection' | 'unsafeLdapFilter' | 'unescapedLdapInput' | 'dangerousLdapOperation' | 'useLdapEscaping' | 'validateLdapInput' | 'useParameterizedLdap' | 'strategyInputValidation' | 'strategySafeLibraries' | 'strategyFilterConstruction';
|
|
2
27
|
export interface Options extends SecurityRuleOptions {
|
|
3
28
|
/** LDAP-related function names to check */
|
|
4
29
|
ldapFunctions?: string[];
|
|
@@ -7,4 +32,6 @@ export interface Options extends SecurityRuleOptions {
|
|
|
7
32
|
/** Functions that validate LDAP input */
|
|
8
33
|
ldapValidationFunctions?: string[];
|
|
9
34
|
}
|
|
10
|
-
|
|
35
|
+
type RuleOptions = [Options?];
|
|
36
|
+
export declare const noLdapInjection: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
37
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noLdapInjection = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-missing-authentication
|
|
8
|
+
* Detects missing authentication checks in route handlers
|
|
9
|
+
* CWE-287: Improper Authentication
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/287.html
|
|
12
|
+
* @see https://owasp.org/www-community/vulnerabilities/Improper_Authentication
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'missingAuthentication' | 'addAuthentication';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Allow missing authentication in test files. Default: false */
|
|
3
18
|
allowInTests?: boolean;
|
|
@@ -10,4 +25,6 @@ export interface Options {
|
|
|
10
25
|
/** Additional patterns to ignore. Default: [] */
|
|
11
26
|
ignorePatterns?: string[];
|
|
12
27
|
}
|
|
13
|
-
|
|
28
|
+
type RuleOptions = [Options?];
|
|
29
|
+
export declare const noMissingAuthentication: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
30
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noMissingAuthentication = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-missing-cors-check
|
|
8
|
+
* Detects missing CORS validation (wildcard CORS, missing origin check)
|
|
9
|
+
* CWE-346: Origin Validation Error
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/346.html
|
|
12
|
+
* @see https://owasp.org/www-community/attacks/CORS_Misconfiguration
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'missingCorsCheck' | 'useOriginValidation' | 'useCorsMiddleware';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Allow missing CORS checks in test files. Default: false */
|
|
3
18
|
allowInTests?: boolean;
|
|
@@ -6,4 +21,6 @@ export interface Options {
|
|
|
6
21
|
/** Additional safe patterns to ignore. Default: [] */
|
|
7
22
|
ignorePatterns?: string[];
|
|
8
23
|
}
|
|
9
|
-
|
|
24
|
+
type RuleOptions = [Options?];
|
|
25
|
+
export declare const noMissingCorsCheck: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
26
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noMissingCorsCheck = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-missing-csrf-protection
|
|
8
|
+
* Detects missing CSRF token validation in POST/PUT/DELETE requests
|
|
9
|
+
* CWE-352: Cross-Site Request Forgery (CSRF)
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/352.html
|
|
12
|
+
* @see https://owasp.org/www-community/attacks/csrf
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'missingCsrfProtection' | 'addCsrfValidation';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Allow missing CSRF protection in test files. Default: false */
|
|
3
18
|
allowInTests?: boolean;
|
|
@@ -8,4 +23,6 @@ export interface Options {
|
|
|
8
23
|
/** Additional safe patterns to ignore. Default: [] */
|
|
9
24
|
ignorePatterns?: string[];
|
|
10
25
|
}
|
|
11
|
-
|
|
26
|
+
type RuleOptions = [Options?];
|
|
27
|
+
export declare const noMissingCsrfProtection: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
28
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noMissingCsrfProtection = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,7 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-missing-security-headers
|
|
8
|
+
* Detects missing security headers in HTTP responses
|
|
9
|
+
* CWE-693: Protection Mechanism Failure
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/693.html
|
|
12
|
+
* @see https://owasp.org/www-project-secure-headers/
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'missingSecurityHeader' | 'addSecurityHeaders' | 'useMiddleware' | 'setHeader';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Required security headers. Default: ['Content-Security-Policy', 'X-Frame-Options', 'X-Content-Type-Options'] */
|
|
3
18
|
requiredHeaders?: string[];
|
|
4
19
|
/** Ignore in test files. Default: true */
|
|
5
20
|
ignoreInTests?: boolean;
|
|
6
21
|
}
|
|
7
|
-
|
|
22
|
+
type RuleOptions = [Options?];
|
|
23
|
+
export declare const noMissingSecurityHeaders: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
24
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noMissingSecurityHeaders = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
export interface Options {
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
type RuleOptions = [Options?];
|
|
9
|
+
export declare const noPasswordInUrl: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
export {};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.noPasswordInUrl = void 0;
|
|
2
9
|
/**
|
|
3
10
|
* @fileoverview Prevent passwords in URLs
|
|
4
11
|
* @see https://owasp.org/www-project-mobile-top-10/
|
|
5
12
|
* @see https://cwe.mitre.org/data/definitions/598.html
|
|
6
13
|
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.noPasswordInUrl = void 0;
|
|
9
14
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
15
|
exports.noPasswordInUrl = (0, eslint_devkit_1.createRule)({
|
|
11
16
|
name: 'no-password-in-url',
|
|
@@ -13,10 +18,6 @@ exports.noPasswordInUrl = (0, eslint_devkit_1.createRule)({
|
|
|
13
18
|
type: 'problem',
|
|
14
19
|
docs: {
|
|
15
20
|
description: 'Prevent passwords in URLs',
|
|
16
|
-
category: 'Security',
|
|
17
|
-
recommended: true,
|
|
18
|
-
owaspMobile: ['M3'],
|
|
19
|
-
cweIds: ["CWE-598"],
|
|
20
21
|
},
|
|
21
22
|
messages: {
|
|
22
23
|
violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
export interface Options {
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
type RuleOptions = [Options?];
|
|
9
|
+
export declare const noPermissiveCors: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
export {};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.noPermissiveCors = void 0;
|
|
2
9
|
/**
|
|
3
10
|
* @fileoverview Prevent overly permissive CORS configuration
|
|
4
11
|
* @see https://owasp.org/www-project-mobile-top-10/
|
|
5
12
|
* @see https://cwe.mitre.org/data/definitions/942.html
|
|
6
13
|
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.noPermissiveCors = void 0;
|
|
9
14
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
15
|
exports.noPermissiveCors = (0, eslint_devkit_1.createRule)({
|
|
11
16
|
name: 'no-permissive-cors',
|
|
@@ -15,10 +20,6 @@ exports.noPermissiveCors = (0, eslint_devkit_1.createRule)({
|
|
|
15
20
|
replacedBy: ['@see eslint-plugin-express-security/no-permissive-cors'],
|
|
16
21
|
docs: {
|
|
17
22
|
description: 'Prevent overly permissive CORS configuration',
|
|
18
|
-
category: 'Security',
|
|
19
|
-
recommended: true,
|
|
20
|
-
owaspMobile: ['M8'],
|
|
21
|
-
cweIds: ["CWE-942"],
|
|
22
23
|
},
|
|
23
24
|
messages: {
|
|
24
25
|
violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
|
|
@@ -44,18 +45,26 @@ exports.noPermissiveCors = (0, eslint_devkit_1.createRule)({
|
|
|
44
45
|
return {
|
|
45
46
|
CallExpression(node) {
|
|
46
47
|
// Check for Access-Control-Allow-Origin: *
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
node.
|
|
50
|
-
node.
|
|
48
|
+
// res.setHeader('Access-Control-Allow-Origin', '*')
|
|
49
|
+
if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
|
|
50
|
+
node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
51
|
+
node.callee.property.name === 'setHeader' &&
|
|
52
|
+
node.arguments[0]?.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
|
|
53
|
+
node.arguments[0].value === 'Access-Control-Allow-Origin' &&
|
|
54
|
+
node.arguments[1]?.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
|
|
55
|
+
node.arguments[1].value === '*') {
|
|
51
56
|
report(node);
|
|
52
57
|
}
|
|
53
58
|
// Check cors({ origin: '*' })
|
|
54
|
-
if (node.type === eslint_devkit_1.AST_NODE_TYPES.
|
|
59
|
+
if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
55
60
|
node.callee.name === 'cors' &&
|
|
56
61
|
node.arguments[0]?.type === eslint_devkit_1.AST_NODE_TYPES.ObjectExpression) {
|
|
57
|
-
const originProp = node.arguments[0].properties.find(p => p.
|
|
58
|
-
|
|
62
|
+
const originProp = node.arguments[0].properties.find((p) => p.type === eslint_devkit_1.AST_NODE_TYPES.Property &&
|
|
63
|
+
p.key.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
64
|
+
p.key.name === 'origin');
|
|
65
|
+
if (originProp &&
|
|
66
|
+
originProp.value.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
|
|
67
|
+
originProp.value.value === '*') {
|
|
59
68
|
report(node);
|
|
60
69
|
}
|
|
61
70
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
export interface Options {
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
type RuleOptions = [Options?];
|
|
9
|
+
export declare const noPiiInLogs: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
export {};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.noPiiInLogs = void 0;
|
|
2
9
|
/**
|
|
3
10
|
* @fileoverview Prevent PII (email, SSN, credit cards) in console logs
|
|
4
11
|
* @see https://owasp.org/www-project-mobile-top-10/
|
|
5
12
|
* @see https://cwe.mitre.org/data/definitions/532.html
|
|
6
13
|
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.noPiiInLogs = void 0;
|
|
9
14
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
15
|
exports.noPiiInLogs = (0, eslint_devkit_1.createRule)({
|
|
11
16
|
name: 'no-pii-in-logs',
|
|
@@ -13,10 +18,6 @@ exports.noPiiInLogs = (0, eslint_devkit_1.createRule)({
|
|
|
13
18
|
type: 'problem',
|
|
14
19
|
docs: {
|
|
15
20
|
description: 'Prevent PII (email, SSN, credit cards) in console logs',
|
|
16
|
-
category: 'Security',
|
|
17
|
-
recommended: true,
|
|
18
|
-
owaspMobile: ['M6'],
|
|
19
|
-
cweIds: ["CWE-532"],
|
|
20
21
|
},
|
|
21
22
|
messages: {
|
|
22
23
|
violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
|
|
@@ -42,21 +43,23 @@ exports.noPiiInLogs = (0, eslint_devkit_1.createRule)({
|
|
|
42
43
|
return {
|
|
43
44
|
CallExpression(node) {
|
|
44
45
|
// Check console.log/error/warn calls
|
|
45
|
-
if (node.type ===
|
|
46
|
-
node.callee.type ===
|
|
46
|
+
if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
|
|
47
|
+
node.callee.object.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
47
48
|
node.callee.object.name === 'console' &&
|
|
49
|
+
node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
|
|
48
50
|
['log', 'error', 'warn', 'info'].includes(node.callee.property.name)) {
|
|
49
51
|
// Check arguments for PII-related property access
|
|
50
52
|
for (const arg of node.arguments) {
|
|
51
|
-
if (arg.type ===
|
|
52
|
-
|
|
53
|
+
if (arg.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
|
|
54
|
+
arg.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier) {
|
|
55
|
+
const propName = arg.property.name.toLowerCase();
|
|
53
56
|
const piiProps = ['email', 'ssn', 'password', 'creditcard', 'phone'];
|
|
54
|
-
if (piiProps.some(p => propName
|
|
57
|
+
if (piiProps.some(p => propName.includes(p))) {
|
|
55
58
|
report(node);
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
// Check string literals mentioning PII
|
|
59
|
-
if (arg.type ===
|
|
62
|
+
if (arg.type === eslint_devkit_1.AST_NODE_TYPES.Literal && typeof arg.value === 'string') {
|
|
60
63
|
const text = arg.value.toLowerCase();
|
|
61
64
|
if (text.includes('email:') || text.includes('ssn:') || text.includes('password:')) {
|
|
62
65
|
report(node);
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-privilege-escalation
|
|
8
|
+
* Detects potential privilege escalation vulnerabilities
|
|
9
|
+
* CWE-269: Improper Privilege Management
|
|
10
|
+
*
|
|
11
|
+
* @see https://cwe.mitre.org/data/definitions/269.html
|
|
12
|
+
* @see https://owasp.org/www-community/vulnerabilities/Improper_Access_Control
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'privilegeEscalation' | 'addRoleCheck';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Allow privilege escalation patterns in test files. Default: false */
|
|
3
18
|
allowInTests?: boolean;
|
|
@@ -10,4 +25,6 @@ export interface Options {
|
|
|
10
25
|
/** Additional patterns to ignore. Default: [] */
|
|
11
26
|
ignorePatterns?: string[];
|
|
12
27
|
}
|
|
13
|
-
|
|
28
|
+
type RuleOptions = [Options?];
|
|
29
|
+
export declare const noPrivilegeEscalation: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
30
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noPrivilegeEscalation = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-redos-vulnerable-regex
|
|
8
|
+
* Detects ReDoS-vulnerable regex patterns in literal regex patterns
|
|
9
|
+
* CWE-400: Uncontrolled Resource Consumption
|
|
10
|
+
*
|
|
11
|
+
* Complements detect-non-literal-regexp by checking literal regex patterns
|
|
12
|
+
*
|
|
13
|
+
* @see https://cwe.mitre.org/data/definitions/400.html
|
|
14
|
+
* @see https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
|
|
15
|
+
*/
|
|
16
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
17
|
+
type MessageIds = 'redosVulnerable' | 'useAtomicGroups' | 'usePossessiveQuantifiers' | 'restructureRegex' | 'useSafeLibrary';
|
|
1
18
|
export interface Options {
|
|
2
19
|
/** Allow certain common patterns. Default: false */
|
|
3
20
|
allowCommonPatterns?: boolean;
|
|
4
21
|
/** Maximum pattern length to analyze. Default: 500 */
|
|
5
22
|
maxPatternLength?: number;
|
|
6
23
|
}
|
|
7
|
-
|
|
24
|
+
type RuleOptions = [Options?];
|
|
25
|
+
export declare const noRedosVulnerableRegex: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
26
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noRedosVulnerableRegex = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-sensitive-data-exposure
|
|
8
|
+
* Detects PII/credentials in logs, responses, or error messages
|
|
9
|
+
* Priority 5: Security with Data Flow Analysis
|
|
10
|
+
* CWE-532: Information Exposure Through Log Files
|
|
11
|
+
*
|
|
12
|
+
* @see https://cwe.mitre.org/data/definitions/532.html
|
|
13
|
+
*/
|
|
14
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
15
|
+
type MessageIds = 'sensitiveDataExposure' | 'redactData' | 'useMasking' | 'removeFromLogs';
|
|
1
16
|
export interface Options {
|
|
2
17
|
/** Sensitive data patterns. Default: ['password', 'secret', 'token', 'key', 'ssn', 'credit', 'card'] */
|
|
3
18
|
sensitivePatterns?: string[];
|
|
@@ -8,4 +23,6 @@ export interface Options {
|
|
|
8
23
|
/** Check API responses. Default: true */
|
|
9
24
|
checkApiResponses?: boolean;
|
|
10
25
|
}
|
|
11
|
-
|
|
26
|
+
type RuleOptions = [Options?];
|
|
27
|
+
export declare const noSensitiveDataExposure: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
|
|
28
|
+
export {};
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.noSensitiveDataExposure = void 0;
|
|
4
9
|
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
export interface Options {
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
type RuleOptions = [Options?];
|
|
9
|
+
export declare const noSensitiveDataInAnalytics: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
export {};
|