@sfdxy/mule-lint 1.8.2 → 1.9.0
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/README.md +12 -2
- package/dist/package.json +1 -1
- package/dist/src/mcp/index.js +1 -1
- package/dist/src/rules/error-handling/TryScopeRule.d.ts +17 -0
- package/dist/src/rules/error-handling/TryScopeRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/TryScopeRule.js +41 -0
- package/dist/src/rules/error-handling/TryScopeRule.js.map +1 -0
- package/dist/src/rules/index.d.ts +1 -1
- package/dist/src/rules/index.d.ts.map +1 -1
- package/dist/src/rules/index.js +14 -1
- package/dist/src/rules/index.js.map +1 -1
- package/dist/src/rules/logging/NewLoggingRules.d.ts +35 -0
- package/dist/src/rules/logging/NewLoggingRules.d.ts.map +1 -0
- package/dist/src/rules/logging/NewLoggingRules.js +89 -0
- package/dist/src/rules/logging/NewLoggingRules.js.map +1 -0
- package/dist/src/rules/performance/ConnectionPoolingRule.d.ts +17 -0
- package/dist/src/rules/performance/ConnectionPoolingRule.d.ts.map +1 -0
- package/dist/src/rules/performance/ConnectionPoolingRule.js +51 -0
- package/dist/src/rules/performance/ConnectionPoolingRule.js.map +1 -0
- package/dist/src/rules/security/InputValidationRule.d.ts +17 -0
- package/dist/src/rules/security/InputValidationRule.d.ts.map +1 -0
- package/dist/src/rules/security/InputValidationRule.js +60 -0
- package/dist/src/rules/security/InputValidationRule.js.map +1 -0
- package/dist/src/rules/security/RateLimitingRule.d.ts +17 -0
- package/dist/src/rules/security/RateLimitingRule.d.ts.map +1 -0
- package/dist/src/rules/security/RateLimitingRule.js +43 -0
- package/dist/src/rules/security/RateLimitingRule.js.map +1 -0
- package/dist/src/rules/security/TlsVersionRule.d.ts +18 -0
- package/dist/src/rules/security/TlsVersionRule.d.ts.map +1 -0
- package/dist/src/rules/security/TlsVersionRule.js +50 -0
- package/dist/src/rules/security/TlsVersionRule.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -203,9 +203,19 @@ mule-lint src/main/mule -f sarif -o results.sarif
|
|
|
203
203
|
| EXP-003 | MUnit Coverage | Info | Experimental | Check for MUnit tests |
|
|
204
204
|
| YAML-001 | Env Files | Warning | Standards | Environment YAML files |
|
|
205
205
|
| YAML-003 | Property Naming | Info | Standards | Property key format |
|
|
206
|
-
|
|
206
|
+
### 2025-2026 Best Practices Rules (NEW)
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
| ID | Name | Severity | Category | Description |
|
|
209
|
+
|----|------|----------|----------|-------------|
|
|
210
|
+
| SEC-002 | TLS Version | Error | Security | Detect deprecated TLS versions (< 1.2) |
|
|
211
|
+
| SEC-003 | Rate Limiting | Warning | Security | APIs should have rate limiting configured |
|
|
212
|
+
| SEC-004 | Input Validation | Warning | Security | Incoming payloads should be validated |
|
|
213
|
+
| LOG-001 | Structured Logging | Info | Logging | Recommend JSON logger format |
|
|
214
|
+
| LOG-004 | Sensitive Data Logging | Error | Logging | Detect PII/secrets in log statements |
|
|
215
|
+
| ERR-001 | Try Scope | Info | Error Handling | Complex operations should use Try scope |
|
|
216
|
+
| PERF-002 | Connection Pooling | Warning | Performance | DB/HTTP should configure connection pools |
|
|
217
|
+
|
|
218
|
+
**Total: 48 rules** across 13 categories.
|
|
209
219
|
|
|
210
220
|
See [Rules Catalog](docs/best-practices/rules-catalog.md) for detailed documentation.
|
|
211
221
|
|
package/dist/package.json
CHANGED
package/dist/src/mcp/index.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* ERR-001: Try Scope Best Practice
|
|
5
|
+
*
|
|
6
|
+
* Complex operations (DB calls, HTTP requests) should use Try scope
|
|
7
|
+
* for granular error isolation and handling.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TryScopeRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "info";
|
|
14
|
+
category: "error-handling";
|
|
15
|
+
validate(doc: Document, _context: ValidationContext): Issue[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=TryScopeRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TryScopeRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/error-handling/TryScopeRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,QAAQ;IACtC,EAAE,SAAa;IACf,IAAI,SAA6B;IACjC,WAAW,SAAiE;IAC5E,QAAQ,EAAG,MAAM,CAAU;IAC3B,QAAQ,EAAG,gBAAgB,CAAU;IAErC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAyChE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TryScopeRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* ERR-001: Try Scope Best Practice
|
|
7
|
+
*
|
|
8
|
+
* Complex operations (DB calls, HTTP requests) should use Try scope
|
|
9
|
+
* for granular error isolation and handling.
|
|
10
|
+
*/
|
|
11
|
+
class TryScopeRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'ERR-001';
|
|
13
|
+
name = 'Try Scope Best Practice';
|
|
14
|
+
description = 'Complex operations should use Try scope for error isolation';
|
|
15
|
+
severity = 'info';
|
|
16
|
+
category = 'error-handling';
|
|
17
|
+
validate(doc, _context) {
|
|
18
|
+
const issues = [];
|
|
19
|
+
// Find flows with multiple risky operations
|
|
20
|
+
const flows = this.select('//*[local-name()="flow"]', doc);
|
|
21
|
+
for (const flow of flows) {
|
|
22
|
+
const flowElement = flow;
|
|
23
|
+
const flowName = flowElement.getAttribute('name') || 'unnamed';
|
|
24
|
+
// Count risky operations (DB, HTTP, external calls)
|
|
25
|
+
const dbOperations = this.select('.//*[namespace-uri()="http://www.mulesoft.org/schema/mule/db"]', flow);
|
|
26
|
+
const httpRequests = this.select('.//*[local-name()="request" and namespace-uri()="http://www.mulesoft.org/schema/mule/http"]', flow);
|
|
27
|
+
const externalCalls = [...dbOperations, ...httpRequests];
|
|
28
|
+
// Check if Try scope exists
|
|
29
|
+
const tryScopes = this.select('.//*[local-name()="try"]', flow);
|
|
30
|
+
// If multiple external calls but no Try scope
|
|
31
|
+
if (externalCalls.length >= 2 && tryScopes.length === 0) {
|
|
32
|
+
issues.push(this.createIssue(flow, `Flow "${flowName}" has ${externalCalls.length} external calls without Try scope isolation`, {
|
|
33
|
+
suggestion: 'Wrap risky operations in Try scope for granular error handling and isolation',
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return issues;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.TryScopeRule = TryScopeRule;
|
|
41
|
+
//# sourceMappingURL=TryScopeRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TryScopeRule.js","sourceRoot":"","sources":["../../../../src/rules/error-handling/TryScopeRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,YAAa,SAAQ,mBAAQ;IACtC,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,yBAAyB,CAAC;IACjC,WAAW,GAAG,6DAA6D,CAAC;IAC5E,QAAQ,GAAG,MAAe,CAAC;IAC3B,QAAQ,GAAG,gBAAyB,CAAC;IAErC,QAAQ,CAAC,GAAa,EAAE,QAA2B;QAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,4CAA4C;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAE3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,IAAe,CAAC;YACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YAE/D,oDAAoD;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAC5B,gEAAgE,EAChE,IAAI,CACP,CAAC;YACF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAC5B,6FAA6F,EAC7F,IAAI,CACP,CAAC;YACF,MAAM,aAAa,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC;YAEzD,4BAA4B;YAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;YAEhE,8CAA8C;YAC9C,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtD,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,IAAI,EACJ,SAAS,QAAQ,SAAS,aAAa,CAAC,MAAM,6CAA6C,EAC3F;oBACI,UAAU,EACN,8EAA8E;iBACrF,CACJ,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAhDD,oCAgDC"}
|
|
@@ -27,7 +27,7 @@ export { AsyncErrorHandlerRule } from './performance/AsyncErrorHandlerRule';
|
|
|
27
27
|
export { LargeChoiceBlockRule } from './performance/LargeChoiceBlockRule';
|
|
28
28
|
/**
|
|
29
29
|
* All available rules - instantiated and ready to use
|
|
30
|
-
* Total:
|
|
30
|
+
* Total: 48 rules (including 7 new 2025-2026 best practices rules)
|
|
31
31
|
*/
|
|
32
32
|
export declare const ALL_RULES: Rule[];
|
|
33
33
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rules/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rules/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAC;AA4EhC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAGpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAG9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,IAAI,EA8E3B,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAExD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
|
package/dist/src/rules/index.js
CHANGED
|
@@ -26,6 +26,7 @@ const MissingErrorHandlerRule_1 = require("./error-handling/MissingErrorHandlerR
|
|
|
26
26
|
const HttpStatusRule_1 = require("./error-handling/HttpStatusRule");
|
|
27
27
|
const CorrelationIdRule_1 = require("./error-handling/CorrelationIdRule");
|
|
28
28
|
const GenericErrorRule_1 = require("./error-handling/GenericErrorRule");
|
|
29
|
+
const TryScopeRule_1 = require("./error-handling/TryScopeRule");
|
|
29
30
|
// Import all rules - Naming
|
|
30
31
|
const FlowNamingRule_1 = require("./naming/FlowNamingRule");
|
|
31
32
|
const FlowCasingRule_1 = require("./naming/FlowCasingRule");
|
|
@@ -34,10 +35,14 @@ const VariableNamingRule_1 = require("./naming/VariableNamingRule");
|
|
|
34
35
|
const HardcodedHttpRule_1 = require("./security/HardcodedHttpRule");
|
|
35
36
|
const HardcodedCredentialsRule_1 = require("./security/HardcodedCredentialsRule");
|
|
36
37
|
const InsecureTlsRule_1 = require("./security/InsecureTlsRule");
|
|
38
|
+
const TlsVersionRule_1 = require("./security/TlsVersionRule");
|
|
39
|
+
const RateLimitingRule_1 = require("./security/RateLimitingRule");
|
|
40
|
+
const InputValidationRule_1 = require("./security/InputValidationRule");
|
|
37
41
|
// Import all rules - Logging
|
|
38
42
|
const LoggerCategoryRule_1 = require("./logging/LoggerCategoryRule");
|
|
39
43
|
const LoggerPayloadRule_1 = require("./logging/LoggerPayloadRule");
|
|
40
44
|
const LoggerInUntilSuccessfulRule_1 = require("./logging/LoggerInUntilSuccessfulRule");
|
|
45
|
+
const NewLoggingRules_1 = require("./logging/NewLoggingRules");
|
|
41
46
|
// Import all rules - Standards
|
|
42
47
|
const ChoiceAntiPatternRule_1 = require("./standards/ChoiceAntiPatternRule");
|
|
43
48
|
const DwlStandardsRule_1 = require("./standards/DwlStandardsRule");
|
|
@@ -53,6 +58,7 @@ const MissingDocNameRule_1 = require("./documentation/MissingDocNameRule");
|
|
|
53
58
|
const ScatterGatherRoutesRule_1 = require("./performance/ScatterGatherRoutesRule");
|
|
54
59
|
const AsyncErrorHandlerRule_1 = require("./performance/AsyncErrorHandlerRule");
|
|
55
60
|
const LargeChoiceBlockRule_1 = require("./performance/LargeChoiceBlockRule");
|
|
61
|
+
const ConnectionPoolingRule_1 = require("./performance/ConnectionPoolingRule");
|
|
56
62
|
// Import all rules - Complexity
|
|
57
63
|
const FlowComplexityRule_1 = require("./complexity/FlowComplexityRule");
|
|
58
64
|
// Import all rules - YAML
|
|
@@ -126,7 +132,7 @@ var LargeChoiceBlockRule_2 = require("./performance/LargeChoiceBlockRule");
|
|
|
126
132
|
Object.defineProperty(exports, "LargeChoiceBlockRule", { enumerable: true, get: function () { return LargeChoiceBlockRule_2.LargeChoiceBlockRule; } });
|
|
127
133
|
/**
|
|
128
134
|
* All available rules - instantiated and ready to use
|
|
129
|
-
* Total:
|
|
135
|
+
* Total: 48 rules (including 7 new 2025-2026 best practices rules)
|
|
130
136
|
*/
|
|
131
137
|
exports.ALL_RULES = [
|
|
132
138
|
// Error Handling Rules (MULE-001, 003, 005, 007, 009)
|
|
@@ -135,6 +141,7 @@ exports.ALL_RULES = [
|
|
|
135
141
|
new HttpStatusRule_1.HttpStatusRule(),
|
|
136
142
|
new CorrelationIdRule_1.CorrelationIdRule(),
|
|
137
143
|
new GenericErrorRule_1.GenericErrorRule(),
|
|
144
|
+
new TryScopeRule_1.TryScopeRule(), // ERR-001: Try Scope Best Practice
|
|
138
145
|
// Naming Rules (MULE-002, 101, 102)
|
|
139
146
|
new FlowNamingRule_1.FlowNamingRule(),
|
|
140
147
|
new FlowCasingRule_1.FlowCasingRule(),
|
|
@@ -143,10 +150,15 @@ exports.ALL_RULES = [
|
|
|
143
150
|
new HardcodedHttpRule_1.HardcodedHttpRule(),
|
|
144
151
|
new HardcodedCredentialsRule_1.HardcodedCredentialsRule(),
|
|
145
152
|
new InsecureTlsRule_1.InsecureTlsRule(),
|
|
153
|
+
new TlsVersionRule_1.TlsVersionRule(), // SEC-002: TLS Version Check
|
|
154
|
+
new RateLimitingRule_1.RateLimitingRule(), // SEC-003: Rate Limiting
|
|
155
|
+
new InputValidationRule_1.InputValidationRule(), // SEC-004: Input Validation
|
|
146
156
|
// Logging Rules (MULE-006, 301, 303)
|
|
147
157
|
new LoggerCategoryRule_1.LoggerCategoryRule(),
|
|
148
158
|
new LoggerPayloadRule_1.LoggerPayloadRule(),
|
|
149
159
|
new LoggerInUntilSuccessfulRule_1.LoggerInUntilSuccessfulRule(),
|
|
160
|
+
new NewLoggingRules_1.StructuredLoggingRule(), // LOG-001: Structured Logging
|
|
161
|
+
new NewLoggingRules_1.SensitiveDataLoggingRule(), // LOG-004: Sensitive Data in Logs
|
|
150
162
|
// Standards Rules (MULE-008, 010, 701)
|
|
151
163
|
new ChoiceAntiPatternRule_1.ChoiceAntiPatternRule(),
|
|
152
164
|
new DwlStandardsRule_1.DwlStandardsRule(),
|
|
@@ -162,6 +174,7 @@ exports.ALL_RULES = [
|
|
|
162
174
|
new ScatterGatherRoutesRule_1.ScatterGatherRoutesRule(),
|
|
163
175
|
new AsyncErrorHandlerRule_1.AsyncErrorHandlerRule(),
|
|
164
176
|
new LargeChoiceBlockRule_1.LargeChoiceBlockRule(),
|
|
177
|
+
new ConnectionPoolingRule_1.ConnectionPoolingRule(), // PERF-002: Connection Pooling
|
|
165
178
|
// Complexity Rules (MULE-801)
|
|
166
179
|
new FlowComplexityRule_1.FlowComplexityRule(),
|
|
167
180
|
// YAML Rules (YAML-001, 003, 004)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rules/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rules/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* LOG-001: Structured Logging Check
|
|
5
|
+
*
|
|
6
|
+
* Recommends JSON logger format over plain text for production
|
|
7
|
+
* applications to enable better log parsing and analysis.
|
|
8
|
+
*/
|
|
9
|
+
export declare class StructuredLoggingRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "info";
|
|
14
|
+
category: "logging";
|
|
15
|
+
validate(doc: Document, context: ValidationContext): Issue[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* LOG-004: Sensitive Data Logging Check
|
|
19
|
+
*
|
|
20
|
+
* Detects logging of sensitive data patterns (passwords, SSN, credit cards)
|
|
21
|
+
* which is a security and compliance violation.
|
|
22
|
+
*
|
|
23
|
+
* This rule looks for patterns where sensitive VARIABLE VALUES are being logged,
|
|
24
|
+
* not just contextual words like "token expired" or "password reset".
|
|
25
|
+
*/
|
|
26
|
+
export declare class SensitiveDataLoggingRule extends BaseRule {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
description: string;
|
|
30
|
+
severity: "error";
|
|
31
|
+
category: "logging";
|
|
32
|
+
private readonly sensitiveValuePatterns;
|
|
33
|
+
validate(doc: Document, _context: ValidationContext): Issue[];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=NewLoggingRules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewLoggingRules.d.ts","sourceRoot":"","sources":["../../../../src/rules/logging/NewLoggingRules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;IAC/C,EAAE,SAAa;IACf,IAAI,SAAwB;IAC5B,WAAW,SAAkD;IAC7D,QAAQ,EAAG,MAAM,CAAU;IAC3B,QAAQ,EAAG,SAAS,CAAU;IAE9B,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAoC/D;AAED;;;;;;;;GAQG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ;IAClD,EAAE,SAAa;IACf,IAAI,SAA4B;IAChC,WAAW,SAA6D;IACxE,QAAQ,EAAG,OAAO,CAAU;IAC5B,QAAQ,EAAG,SAAS,CAAU;IAI9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAQrC;IAEF,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAmChE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SensitiveDataLoggingRule = exports.StructuredLoggingRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* LOG-001: Structured Logging Check
|
|
7
|
+
*
|
|
8
|
+
* Recommends JSON logger format over plain text for production
|
|
9
|
+
* applications to enable better log parsing and analysis.
|
|
10
|
+
*/
|
|
11
|
+
class StructuredLoggingRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'LOG-001';
|
|
13
|
+
name = 'Structured Logging';
|
|
14
|
+
description = 'Recommend JSON logger format over plain text';
|
|
15
|
+
severity = 'info';
|
|
16
|
+
category = 'logging';
|
|
17
|
+
validate(doc, context) {
|
|
18
|
+
const issues = [];
|
|
19
|
+
// Check if this is global.xml or a config file
|
|
20
|
+
if (!context.relativePath.includes('global') &&
|
|
21
|
+
!context.relativePath.includes('config')) {
|
|
22
|
+
return issues;
|
|
23
|
+
}
|
|
24
|
+
// Look for JSON logger module configuration
|
|
25
|
+
const jsonLoggerConfig = this.select('//*[contains(local-name(), "json-logger") or contains(local-name(), "jsonlogger")]', doc);
|
|
26
|
+
// Look for standard logger elements
|
|
27
|
+
const standardLoggers = this.select('//*[local-name()="logger"]', doc);
|
|
28
|
+
// If using standard loggers but no JSON logger configured
|
|
29
|
+
if (standardLoggers.length > 0 && jsonLoggerConfig.length === 0) {
|
|
30
|
+
issues.push(this.createIssue(standardLoggers[0], 'Project uses standard logger instead of JSON structured logging', {
|
|
31
|
+
suggestion: 'Consider using JSON Logger Module for structured logging in production. This enables better log aggregation and analysis.',
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
return issues;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.StructuredLoggingRule = StructuredLoggingRule;
|
|
38
|
+
/**
|
|
39
|
+
* LOG-004: Sensitive Data Logging Check
|
|
40
|
+
*
|
|
41
|
+
* Detects logging of sensitive data patterns (passwords, SSN, credit cards)
|
|
42
|
+
* which is a security and compliance violation.
|
|
43
|
+
*
|
|
44
|
+
* This rule looks for patterns where sensitive VARIABLE VALUES are being logged,
|
|
45
|
+
* not just contextual words like "token expired" or "password reset".
|
|
46
|
+
*/
|
|
47
|
+
class SensitiveDataLoggingRule extends BaseRule_1.BaseRule {
|
|
48
|
+
id = 'LOG-004';
|
|
49
|
+
name = 'Sensitive Data in Logs';
|
|
50
|
+
description = 'Log statements should not contain sensitive data values';
|
|
51
|
+
severity = 'error';
|
|
52
|
+
category = 'logging';
|
|
53
|
+
// Patterns that suggest actual sensitive VALUES are being logged
|
|
54
|
+
// e.g., "password: " ++ password, vars.token, payload.secret
|
|
55
|
+
sensitiveValuePatterns = [
|
|
56
|
+
/vars\.(password|secret|token|apiKey|privateKey|accessToken|refreshToken|ssn|pin)\b/i,
|
|
57
|
+
/payload\.(password|secret|token|apiKey|privateKey|accessToken|refreshToken|ssn|pin)\b/i,
|
|
58
|
+
/attributes\.(password|secret|token)\b/i,
|
|
59
|
+
/\$\{.*password.*\}/i,
|
|
60
|
+
/\$\{.*secret.*\}/i,
|
|
61
|
+
/\$\{secure::.*\}/i, // Logging secure properties is bad
|
|
62
|
+
/\+\+\s*(password|secret|token|apiKey)\b/i, // Concatenating sensitive vars
|
|
63
|
+
];
|
|
64
|
+
validate(doc, _context) {
|
|
65
|
+
const issues = [];
|
|
66
|
+
// Find all logger elements (standard and json-logger)
|
|
67
|
+
const loggers = this.select('//*[local-name()="logger"]', doc);
|
|
68
|
+
for (const logger of loggers) {
|
|
69
|
+
const element = logger;
|
|
70
|
+
const message = element.getAttribute('message') || '';
|
|
71
|
+
// Only check if it contains DataWeave expressions
|
|
72
|
+
if (!message.includes('#[') && !message.includes('${')) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// Check for patterns that suggest actual values are being logged
|
|
76
|
+
for (const pattern of this.sensitiveValuePatterns) {
|
|
77
|
+
if (pattern.test(message)) {
|
|
78
|
+
issues.push(this.createIssue(logger, `Logger may expose sensitive data value: pattern "${pattern.source}" detected`, {
|
|
79
|
+
suggestion: 'Mask sensitive data before logging using DataWeave masking functions or remove the sensitive variable reference',
|
|
80
|
+
}));
|
|
81
|
+
break; // Only report once per logger
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return issues;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.SensitiveDataLoggingRule = SensitiveDataLoggingRule;
|
|
89
|
+
//# sourceMappingURL=NewLoggingRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewLoggingRules.js","sourceRoot":"","sources":["../../../../src/rules/logging/NewLoggingRules.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,qBAAsB,SAAQ,mBAAQ;IAC/C,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,oBAAoB,CAAC;IAC5B,WAAW,GAAG,8CAA8C,CAAC;IAC7D,QAAQ,GAAG,MAAe,CAAC;IAC3B,QAAQ,GAAG,SAAkB,CAAC;IAE9B,QAAQ,CAAC,GAAa,EAAE,OAA0B;QAC9C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,+CAA+C;QAC/C,IACI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC1C,CAAC;YACC,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,4CAA4C;QAC5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAChC,oFAAoF,EACpF,GAAG,CACN,CAAC;QAEF,oCAAoC;QACpC,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QAEvE,0DAA0D;QAC1D,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,eAAe,CAAC,CAAC,CAAC,EAClB,iEAAiE,EACjE;gBACI,UAAU,EACN,2HAA2H;aAClI,CACJ,CACJ,CAAC;QACN,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AA3CD,sDA2CC;AAED;;;;;;;;GAQG;AACH,MAAa,wBAAyB,SAAQ,mBAAQ;IAClD,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,wBAAwB,CAAC;IAChC,WAAW,GAAG,yDAAyD,CAAC;IACxE,QAAQ,GAAG,OAAgB,CAAC;IAC5B,QAAQ,GAAG,SAAkB,CAAC;IAE9B,iEAAiE;IACjE,6DAA6D;IAC5C,sBAAsB,GAAG;QACtC,qFAAqF;QACrF,wFAAwF;QACxF,wCAAwC;QACxC,qBAAqB;QACrB,mBAAmB;QACnB,mBAAmB,EAAE,mCAAmC;QACxD,0CAA0C,EAAE,+BAA+B;KAC9E,CAAC;IAEF,QAAQ,CAAC,GAAa,EAAE,QAA2B;QAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,sDAAsD;QACtD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;QAE/D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,MAAiB,CAAC;YAClC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAEtD,kDAAkD;YAClD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,SAAS;YACb,CAAC;YAED,iEAAiE;YACjE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAChD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,MAAM,EACN,oDAAoD,OAAO,CAAC,MAAM,YAAY,EAC9E;wBACI,UAAU,EACN,iHAAiH;qBACxH,CACJ,CACJ,CAAC;oBACF,MAAM,CAAC,8BAA8B;gBACzC,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAtDD,4DAsDC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* PERF-002: Connection Pooling Check
|
|
5
|
+
*
|
|
6
|
+
* DB and HTTP connectors should configure connection pools
|
|
7
|
+
* for optimal performance and resource management.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ConnectionPoolingRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "warning";
|
|
14
|
+
category: "performance";
|
|
15
|
+
validate(doc: Document, _context: ValidationContext): Issue[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=ConnectionPoolingRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionPoolingRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;IAC/C,EAAE,SAAc;IAChB,IAAI,SAAwB;IAC5B,WAAW,SAA0D;IACrE,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,aAAa,CAAU;IAElC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CA+DhE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConnectionPoolingRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* PERF-002: Connection Pooling Check
|
|
7
|
+
*
|
|
8
|
+
* DB and HTTP connectors should configure connection pools
|
|
9
|
+
* for optimal performance and resource management.
|
|
10
|
+
*/
|
|
11
|
+
class ConnectionPoolingRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'PERF-002';
|
|
13
|
+
name = 'Connection Pooling';
|
|
14
|
+
description = 'DB/HTTP connectors should configure connection pools';
|
|
15
|
+
severity = 'warning';
|
|
16
|
+
category = 'performance';
|
|
17
|
+
validate(doc, _context) {
|
|
18
|
+
const issues = [];
|
|
19
|
+
// Check HTTP request configurations
|
|
20
|
+
const httpConfigs = this.select('//*[local-name()="request-config" and namespace-uri()="http://www.mulesoft.org/schema/mule/http"]', doc);
|
|
21
|
+
for (const config of httpConfigs) {
|
|
22
|
+
const element = config;
|
|
23
|
+
const name = element.getAttribute('name') || 'unnamed';
|
|
24
|
+
// Check for connection pooling attributes
|
|
25
|
+
const hasPooling = element.hasAttribute('maxConnections') ||
|
|
26
|
+
element.hasAttribute('connectionIdleTimeout') ||
|
|
27
|
+
this.select('.//*[local-name()="pooling-profile"]', config).length > 0;
|
|
28
|
+
if (!hasPooling) {
|
|
29
|
+
issues.push(this.createIssue(config, `HTTP request config "${name}" has no connection pooling configured`, {
|
|
30
|
+
suggestion: 'Add maxConnections and connectionIdleTimeout for optimal connection management',
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Check Database configurations
|
|
35
|
+
const dbConfigs = this.select('//*[local-name()="config" and namespace-uri()="http://www.mulesoft.org/schema/mule/db"]', doc);
|
|
36
|
+
for (const config of dbConfigs) {
|
|
37
|
+
const element = config;
|
|
38
|
+
const name = element.getAttribute('name') || 'unnamed';
|
|
39
|
+
// Check for pooling profile
|
|
40
|
+
const hasPooling = this.select('.//*[local-name()="pooling-profile"]', config).length > 0;
|
|
41
|
+
if (!hasPooling) {
|
|
42
|
+
issues.push(this.createIssue(config, `Database config "${name}" has no connection pooling configured`, {
|
|
43
|
+
suggestion: 'Add db:pooling-profile with maxPoolSize and minPoolSize for optimal performance',
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return issues;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.ConnectionPoolingRule = ConnectionPoolingRule;
|
|
51
|
+
//# sourceMappingURL=ConnectionPoolingRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionPoolingRule.js","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,qBAAsB,SAAQ,mBAAQ;IAC/C,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,oBAAoB,CAAC;IAC5B,WAAW,GAAG,sDAAsD,CAAC;IACrE,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,aAAsB,CAAC;IAElC,QAAQ,CAAC,GAAa,EAAE,QAA2B;QAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,oCAAoC;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC3B,mGAAmG,EACnG,GAAG,CACN,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAiB,CAAC;YAClC,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YAEvD,0CAA0C;YAC1C,MAAM,UAAU,GACZ,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC;gBACtC,OAAO,CAAC,YAAY,CAAC,uBAAuB,CAAC;gBAC7C,IAAI,CAAC,MAAM,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAE3E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,MAAM,EACN,wBAAwB,IAAI,wCAAwC,EACpE;oBACI,UAAU,EACN,gFAAgF;iBACvF,CACJ,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,gCAAgC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CACzB,yFAAyF,EACzF,GAAG,CACN,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAiB,CAAC;YAClC,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YAEvD,4BAA4B;YAC5B,MAAM,UAAU,GACZ,IAAI,CAAC,MAAM,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAE3E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,MAAM,EACN,oBAAoB,IAAI,wCAAwC,EAChE;oBACI,UAAU,EACN,iFAAiF;iBACxF,CACJ,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAtED,sDAsEC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* SEC-004: Input Validation Check
|
|
5
|
+
*
|
|
6
|
+
* Incoming payloads should be validated using JSON or XML schema validation
|
|
7
|
+
* to prevent injection attacks and malformed data processing.
|
|
8
|
+
*/
|
|
9
|
+
export declare class InputValidationRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "warning";
|
|
14
|
+
category: "security";
|
|
15
|
+
validate(doc: Document, context: ValidationContext): Issue[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=InputValidationRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputValidationRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/security/InputValidationRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;IAC7C,EAAE,SAAa;IACf,IAAI,SAAsB;IAC1B,WAAW,SAAkE;IAC7E,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,UAAU,CAAU;IAE/B,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAgE/D"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InputValidationRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* SEC-004: Input Validation Check
|
|
7
|
+
*
|
|
8
|
+
* Incoming payloads should be validated using JSON or XML schema validation
|
|
9
|
+
* to prevent injection attacks and malformed data processing.
|
|
10
|
+
*/
|
|
11
|
+
class InputValidationRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'SEC-004';
|
|
13
|
+
name = 'Input Validation';
|
|
14
|
+
description = 'Incoming payloads should be validated with schema validation';
|
|
15
|
+
severity = 'warning';
|
|
16
|
+
category = 'security';
|
|
17
|
+
validate(doc, context) {
|
|
18
|
+
const issues = [];
|
|
19
|
+
// Skip non-interface files
|
|
20
|
+
if (!context.relativePath.includes('interface') && !context.relativePath.includes('impl')) {
|
|
21
|
+
return issues;
|
|
22
|
+
}
|
|
23
|
+
// Find HTTP listeners that accept POST/PUT/PATCH
|
|
24
|
+
const flows = this.select('//*[local-name()="flow"]', doc);
|
|
25
|
+
for (const flow of flows) {
|
|
26
|
+
const flowElement = flow;
|
|
27
|
+
const flowName = flowElement.getAttribute('name') || '';
|
|
28
|
+
// Check if flow has HTTP listener with body-accepting methods
|
|
29
|
+
const listeners = this.select('.//*[local-name()="listener"]', flow);
|
|
30
|
+
if (listeners.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
// Check for POST, PUT, PATCH patterns in flow name (APIKit generated)
|
|
33
|
+
const acceptsBody = flowName.includes('post:') ||
|
|
34
|
+
flowName.includes('put:') ||
|
|
35
|
+
flowName.includes('patch:');
|
|
36
|
+
if (!acceptsBody)
|
|
37
|
+
continue;
|
|
38
|
+
// Check for validation in the flow
|
|
39
|
+
const hasValidation = this.select('.//*[local-name()="validate-schema" or local-name()="json-schema-validator" or local-name()="schema-validator" or contains(local-name(), "validation")]', flow).length > 0;
|
|
40
|
+
// Check for DataWeave validation patterns
|
|
41
|
+
const transforms = this.select('.//*[local-name()="transform"]', flow);
|
|
42
|
+
let hasInlineValidation = false;
|
|
43
|
+
for (const transform of transforms) {
|
|
44
|
+
const content = transform.textContent || '';
|
|
45
|
+
if (content.includes('validate') || content.includes('match')) {
|
|
46
|
+
hasInlineValidation = true;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (!hasValidation && !hasInlineValidation) {
|
|
51
|
+
issues.push(this.createIssue(flow, `Flow "${flowName}" accepts request body but has no input validation`, {
|
|
52
|
+
suggestion: 'Add JSON/XML schema validation or DataWeave validation to prevent injection attacks',
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return issues;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.InputValidationRule = InputValidationRule;
|
|
60
|
+
//# sourceMappingURL=InputValidationRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputValidationRule.js","sourceRoot":"","sources":["../../../../src/rules/security/InputValidationRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,mBAAoB,SAAQ,mBAAQ;IAC7C,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,kBAAkB,CAAC;IAC1B,WAAW,GAAG,8DAA8D,CAAC;IAC7E,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,UAAmB,CAAC;IAE/B,QAAQ,CAAC,GAAa,EAAE,OAA0B;QAC9C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,2BAA2B;QAC3B,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACxF,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,iDAAiD;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAE3D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,IAAe,CAAC;YACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAExD,8DAA8D;YAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CACzB,+BAA+B,EAC/B,IAAI,CACP,CAAC;YAEF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAErC,sEAAsE;YACtE,MAAM,WAAW,GACb,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC1B,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACzB,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,CAAC,WAAW;gBAAE,SAAS;YAE3B,mCAAmC;YACnC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAC7B,yJAAyJ,EACzJ,IAAI,CACP,CAAC,MAAM,GAAG,CAAC,CAAC;YAEb,0CAA0C;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,gCAAgC,EAAE,IAAI,CAAC,CAAC;YACvE,IAAI,mBAAmB,GAAG,KAAK,CAAC;YAChC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAI,SAAqB,CAAC,WAAW,IAAI,EAAE,CAAC;gBACzD,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5D,mBAAmB,GAAG,IAAI,CAAC;oBAC3B,MAAM;gBACV,CAAC;YACL,CAAC;YAED,IAAI,CAAC,aAAa,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,IAAI,EACJ,SAAS,QAAQ,oDAAoD,EACrE;oBACI,UAAU,EACN,qFAAqF;iBAC5F,CACJ,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAvED,kDAuEC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* SEC-003: Rate Limiting Policy Check
|
|
5
|
+
*
|
|
6
|
+
* Production APIs should have rate limiting or throttling configured
|
|
7
|
+
* to prevent DoS attacks and manage API consumption.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RateLimitingRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "warning";
|
|
14
|
+
category: "security";
|
|
15
|
+
validate(doc: Document, context: ValidationContext): Issue[];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=RateLimitingRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimitingRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/security/RateLimitingRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC1C,EAAE,SAAa;IACf,IAAI,SAA0B;IAC9B,WAAW,SAA6D;IACxE,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,UAAU,CAAU;IAE/B,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;CA+C/D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RateLimitingRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* SEC-003: Rate Limiting Policy Check
|
|
7
|
+
*
|
|
8
|
+
* Production APIs should have rate limiting or throttling configured
|
|
9
|
+
* to prevent DoS attacks and manage API consumption.
|
|
10
|
+
*/
|
|
11
|
+
class RateLimitingRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'SEC-003';
|
|
13
|
+
name = 'Rate Limiting Policy';
|
|
14
|
+
description = 'APIs should have rate limiting or throttling configured';
|
|
15
|
+
severity = 'warning';
|
|
16
|
+
category = 'security';
|
|
17
|
+
validate(doc, context) {
|
|
18
|
+
const issues = [];
|
|
19
|
+
// Skip if not an API listener (interface.xml or similar)
|
|
20
|
+
if (!context.relativePath.includes('interface') && !context.relativePath.includes('api')) {
|
|
21
|
+
return issues;
|
|
22
|
+
}
|
|
23
|
+
// Find HTTP listeners
|
|
24
|
+
const httpListeners = this.select('//*[local-name()="listener" and namespace-uri()="http://www.mulesoft.org/schema/mule/http"]', doc);
|
|
25
|
+
if (httpListeners.length === 0) {
|
|
26
|
+
return issues;
|
|
27
|
+
}
|
|
28
|
+
// Check for rate limiting policies (apikit-config, throttling-policy, etc.)
|
|
29
|
+
const rateLimitingElements = this.select('//*[contains(local-name(), "rate") or contains(local-name(), "throttl") or contains(local-name(), "spike")]', doc);
|
|
30
|
+
// Check for policy references in API Kit router
|
|
31
|
+
const policyRefs = this.select('//*[local-name()="policy" or contains(@policies, "rate") or contains(@policies, "throttl")]', doc);
|
|
32
|
+
// If no rate limiting found and this looks like an API
|
|
33
|
+
if (rateLimitingElements.length === 0 && policyRefs.length === 0) {
|
|
34
|
+
// Only report once per file, on the first listener
|
|
35
|
+
issues.push(this.createIssue(httpListeners[0], 'API endpoint has no rate limiting or throttling configured', {
|
|
36
|
+
suggestion: 'Configure rate limiting via API Manager policies or add throttling:config to protect against DoS attacks',
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
return issues;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.RateLimitingRule = RateLimitingRule;
|
|
43
|
+
//# sourceMappingURL=RateLimitingRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimitingRule.js","sourceRoot":"","sources":["../../../../src/rules/security/RateLimitingRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,gBAAiB,SAAQ,mBAAQ;IAC1C,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,sBAAsB,CAAC;IAC9B,WAAW,GAAG,yDAAyD,CAAC;IACxE,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,UAAmB,CAAC;IAE/B,QAAQ,CAAC,GAAa,EAAE,OAA0B;QAC9C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,yDAAyD;QACzD,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACvF,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,sBAAsB;QACtB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAC7B,6FAA6F,EAC7F,GAAG,CACN,CAAC;QAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,4EAA4E;QAC5E,MAAM,oBAAoB,GAAG,IAAI,CAAC,MAAM,CACpC,6GAA6G,EAC7G,GAAG,CACN,CAAC;QAEF,gDAAgD;QAChD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAC1B,6FAA6F,EAC7F,GAAG,CACN,CAAC;QAEF,uDAAuD;QACvD,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/D,mDAAmD;YACnD,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,aAAa,CAAC,CAAC,CAAC,EAChB,4DAA4D,EAC5D;gBACI,UAAU,EACN,0GAA0G;aACjH,CACJ,CACJ,CAAC;QACN,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAtDD,4CAsDC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ValidationContext, Issue } from '../../types';
|
|
2
|
+
import { BaseRule } from '../base/BaseRule';
|
|
3
|
+
/**
|
|
4
|
+
* SEC-002: TLS Version Check
|
|
5
|
+
*
|
|
6
|
+
* Detects use of deprecated TLS versions (< 1.2) which are security vulnerabilities.
|
|
7
|
+
* TLS 1.0 and 1.1 are deprecated and should not be used per 2025 security standards.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TlsVersionRule extends BaseRule {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
severity: "error";
|
|
14
|
+
category: "security";
|
|
15
|
+
private readonly deprecatedProtocols;
|
|
16
|
+
validate(doc: Document, _context: ValidationContext): Issue[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=TlsVersionRule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TlsVersionRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/security/TlsVersionRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IACxC,EAAE,SAAa;IACf,IAAI,SAAuB;IAC3B,WAAW,SAAmD;IAC9D,QAAQ,EAAG,OAAO,CAAU;IAC5B,QAAQ,EAAG,UAAU,CAAU;IAE/B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqD;IAEzF,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CA+DhE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TlsVersionRule = void 0;
|
|
4
|
+
const BaseRule_1 = require("../base/BaseRule");
|
|
5
|
+
/**
|
|
6
|
+
* SEC-002: TLS Version Check
|
|
7
|
+
*
|
|
8
|
+
* Detects use of deprecated TLS versions (< 1.2) which are security vulnerabilities.
|
|
9
|
+
* TLS 1.0 and 1.1 are deprecated and should not be used per 2025 security standards.
|
|
10
|
+
*/
|
|
11
|
+
class TlsVersionRule extends BaseRule_1.BaseRule {
|
|
12
|
+
id = 'SEC-002';
|
|
13
|
+
name = 'TLS Version Check';
|
|
14
|
+
description = 'Detect use of deprecated TLS versions (< 1.2)';
|
|
15
|
+
severity = 'error';
|
|
16
|
+
category = 'security';
|
|
17
|
+
deprecatedProtocols = ['TLSv1', 'TLSv1.0', 'TLSv1.1', 'SSLv3', 'SSLv2'];
|
|
18
|
+
validate(doc, _context) {
|
|
19
|
+
const issues = [];
|
|
20
|
+
// Find all TLS context configurations
|
|
21
|
+
const tlsContexts = this.select('//*[local-name()="context"]', doc);
|
|
22
|
+
for (const context of tlsContexts) {
|
|
23
|
+
const element = context;
|
|
24
|
+
const enabledProtocols = element.getAttribute('enabledProtocols');
|
|
25
|
+
if (enabledProtocols) {
|
|
26
|
+
const protocols = enabledProtocols.split(',').map((p) => p.trim());
|
|
27
|
+
const deprecated = protocols.filter((p) => this.deprecatedProtocols.some((dp) => p.toUpperCase() === dp.toUpperCase()));
|
|
28
|
+
if (deprecated.length > 0) {
|
|
29
|
+
issues.push(this.createIssue(context, `Deprecated TLS protocol(s) enabled: ${deprecated.join(', ')}`, {
|
|
30
|
+
suggestion: 'Use TLSv1.2 or TLSv1.3 only. Remove deprecated protocols from enabledProtocols',
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Check for explicit protocol configurations in tls:context
|
|
36
|
+
const protocolElements = this.select('//*[local-name()="enabled-protocols"]/*[local-name()="protocol"]', doc);
|
|
37
|
+
for (const protocol of protocolElements) {
|
|
38
|
+
const element = protocol;
|
|
39
|
+
const value = element.textContent?.trim() || '';
|
|
40
|
+
if (this.deprecatedProtocols.some((dp) => value.toUpperCase() === dp.toUpperCase())) {
|
|
41
|
+
issues.push(this.createIssue(protocol, `Deprecated TLS protocol configured: ${value}`, {
|
|
42
|
+
suggestion: 'Remove deprecated protocol. Use TLSv1.2 or TLSv1.3 only',
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return issues;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.TlsVersionRule = TlsVersionRule;
|
|
50
|
+
//# sourceMappingURL=TlsVersionRule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TlsVersionRule.js","sourceRoot":"","sources":["../../../../src/rules/security/TlsVersionRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;GAKG;AACH,MAAa,cAAe,SAAQ,mBAAQ;IACxC,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,mBAAmB,CAAC;IAC3B,WAAW,GAAG,+CAA+C,CAAC;IAC9D,QAAQ,GAAG,OAAgB,CAAC;IAC5B,QAAQ,GAAG,UAAmB,CAAC;IAEd,mBAAmB,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEzF,QAAQ,CAAC,GAAa,EAAE,QAA2B;QAC/C,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,sCAAsC;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAEpE,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,OAAkB,CAAC;YACnC,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;YAElE,IAAI,gBAAgB,EAAE,CAAC;gBACnB,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBACnE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CACzB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,CAC/C,CACJ,CAAC;gBAEF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,OAAO,EACP,uCAAuC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC9D;wBACI,UAAU,EACN,gFAAgF;qBACvF,CACJ,CACJ,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;QAED,4DAA4D;QAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAChC,kEAAkE,EAClE,GAAG,CACN,CAAC;QAEF,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,QAAmB,CAAC;YACpC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAEhD,IACI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CACzB,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE,CACnD,EACH,CAAC;gBACC,MAAM,CAAC,IAAI,CACP,IAAI,CAAC,WAAW,CACZ,QAAQ,EACR,uCAAuC,KAAK,EAAE,EAC9C;oBACI,UAAU,EACN,yDAAyD;iBAChE,CACJ,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAxED,wCAwEC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfdxy/mule-lint",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Static analysis tool for MuleSoft applications - supports humans, AI agents, and CI/CD pipelines",
|
|
5
5
|
"author": "Avinava",
|
|
6
6
|
"license": "MIT",
|
|
@@ -70,4 +70,4 @@
|
|
|
70
70
|
"url": "https://github.com/Avinava/mule-lint/issues"
|
|
71
71
|
},
|
|
72
72
|
"homepage": "https://github.com/Avinava/mule-lint#readme"
|
|
73
|
-
}
|
|
73
|
+
}
|