beddel 0.1.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 +297 -0
- package/dist/agents/agentRegistry.d.ts +68 -0
- package/dist/agents/agentRegistry.d.ts.map +1 -0
- package/dist/agents/agentRegistry.js +222 -0
- package/dist/agents/agentRegistry.js.map +1 -0
- package/dist/agents/formatter-agent.d.ts +10 -0
- package/dist/agents/formatter-agent.d.ts.map +1 -0
- package/dist/agents/formatter-agent.js +49 -0
- package/dist/agents/formatter-agent.js.map +1 -0
- package/dist/agents/genkit-agent.d.ts +12 -0
- package/dist/agents/genkit-agent.d.ts.map +1 -0
- package/dist/agents/genkit-agent.js +119 -0
- package/dist/agents/genkit-agent.js.map +1 -0
- package/dist/agents/i18n-messages.d.ts +17 -0
- package/dist/agents/i18n-messages.d.ts.map +1 -0
- package/dist/agents/i18n-messages.js +92 -0
- package/dist/agents/i18n-messages.js.map +1 -0
- package/dist/agents/index.d.ts +10 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +26 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/pipeline.d.ts +15 -0
- package/dist/agents/pipeline.d.ts.map +1 -0
- package/dist/agents/pipeline.js +45 -0
- package/dist/agents/pipeline.js.map +1 -0
- package/dist/agents/schema-factory.d.ts +40 -0
- package/dist/agents/schema-factory.d.ts.map +1 -0
- package/dist/agents/schema-factory.js +121 -0
- package/dist/agents/schema-factory.js.map +1 -0
- package/dist/agents/translation-validators.d.ts +26 -0
- package/dist/agents/translation-validators.d.ts.map +1 -0
- package/dist/agents/translation-validators.js +77 -0
- package/dist/agents/translation-validators.js.map +1 -0
- package/dist/agents/translator-agents.d.ts +184 -0
- package/dist/agents/translator-agents.d.ts.map +1 -0
- package/dist/agents/translator-agents.js +613 -0
- package/dist/agents/translator-agents.js.map +1 -0
- package/dist/agents/types/translation.types.d.ts +100 -0
- package/dist/agents/types/translation.types.d.ts.map +1 -0
- package/dist/agents/types/translation.types.js +3 -0
- package/dist/agents/types/translation.types.js.map +1 -0
- package/dist/agents/validator-agent.d.ts +42 -0
- package/dist/agents/validator-agent.d.ts.map +1 -0
- package/dist/agents/validator-agent.js +122 -0
- package/dist/agents/validator-agent.js.map +1 -0
- package/dist/audit/auditTrail.d.ts +55 -0
- package/dist/audit/auditTrail.d.ts.map +1 -0
- package/dist/audit/auditTrail.js +93 -0
- package/dist/audit/auditTrail.js.map +1 -0
- package/dist/compliance/gdprEngine.d.ts +44 -0
- package/dist/compliance/gdprEngine.d.ts.map +1 -0
- package/dist/compliance/gdprEngine.js +178 -0
- package/dist/compliance/gdprEngine.js.map +1 -0
- package/dist/compliance/lgpdEngine.d.ts +51 -0
- package/dist/compliance/lgpdEngine.d.ts.map +1 -0
- package/dist/compliance/lgpdEngine.js +221 -0
- package/dist/compliance/lgpdEngine.js.map +1 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/firebase/tenantManager.d.ts +84 -0
- package/dist/firebase/tenantManager.d.ts.map +1 -0
- package/dist/firebase/tenantManager.js +378 -0
- package/dist/firebase/tenantManager.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/integration/secure-yaml-runtime.d.ts +68 -0
- package/dist/integration/secure-yaml-runtime.d.ts.map +1 -0
- package/dist/integration/secure-yaml-runtime.js +245 -0
- package/dist/integration/secure-yaml-runtime.js.map +1 -0
- package/dist/parser/secure-yaml-parser.d.ts +62 -0
- package/dist/parser/secure-yaml-parser.d.ts.map +1 -0
- package/dist/parser/secure-yaml-parser.js +234 -0
- package/dist/parser/secure-yaml-parser.js.map +1 -0
- package/dist/performance/autoscaling.d.ts +100 -0
- package/dist/performance/autoscaling.d.ts.map +1 -0
- package/dist/performance/autoscaling.js +339 -0
- package/dist/performance/autoscaling.js.map +1 -0
- package/dist/performance/benchmark.d.ts +104 -0
- package/dist/performance/benchmark.d.ts.map +1 -0
- package/dist/performance/benchmark.js +514 -0
- package/dist/performance/benchmark.js.map +1 -0
- package/dist/performance/index.d.ts +14 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +35 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/performance/monitor.d.ts +126 -0
- package/dist/performance/monitor.d.ts.map +1 -0
- package/dist/performance/monitor.js +324 -0
- package/dist/performance/monitor.js.map +1 -0
- package/dist/performance/streaming.d.ts +82 -0
- package/dist/performance/streaming.d.ts.map +1 -0
- package/dist/performance/streaming.js +287 -0
- package/dist/performance/streaming.js.map +1 -0
- package/dist/runtime/audit.d.ts +240 -0
- package/dist/runtime/audit.d.ts.map +1 -0
- package/dist/runtime/audit.js +641 -0
- package/dist/runtime/audit.js.map +1 -0
- package/dist/runtime/declarativeAgentRuntime.d.ts +123 -0
- package/dist/runtime/declarativeAgentRuntime.d.ts.map +1 -0
- package/dist/runtime/declarativeAgentRuntime.js +576 -0
- package/dist/runtime/declarativeAgentRuntime.js.map +1 -0
- package/dist/runtime/isolatedRuntime.d.ts +119 -0
- package/dist/runtime/isolatedRuntime.d.ts.map +1 -0
- package/dist/runtime/isolatedRuntime.js +425 -0
- package/dist/runtime/isolatedRuntime.js.map +1 -0
- package/dist/runtime/schemaCompiler.d.ts +35 -0
- package/dist/runtime/schemaCompiler.d.ts.map +1 -0
- package/dist/runtime/schemaCompiler.js +151 -0
- package/dist/runtime/schemaCompiler.js.map +1 -0
- package/dist/runtime/simpleRuntime.d.ts +57 -0
- package/dist/runtime/simpleRuntime.d.ts.map +1 -0
- package/dist/runtime/simpleRuntime.js +187 -0
- package/dist/runtime/simpleRuntime.js.map +1 -0
- package/dist/security/dashboard.d.ts +89 -0
- package/dist/security/dashboard.d.ts.map +1 -0
- package/dist/security/dashboard.js +300 -0
- package/dist/security/dashboard.js.map +1 -0
- package/dist/security/hardening.d.ts +130 -0
- package/dist/security/hardening.d.ts.map +1 -0
- package/dist/security/hardening.js +414 -0
- package/dist/security/hardening.js.map +1 -0
- package/dist/security/index.d.ts +128 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +353 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/monitor.d.ts +88 -0
- package/dist/security/monitor.d.ts.map +1 -0
- package/dist/security/monitor.js +356 -0
- package/dist/security/monitor.js.map +1 -0
- package/dist/security/scanner.d.ts +104 -0
- package/dist/security/scanner.d.ts.map +1 -0
- package/dist/security/scanner.js +298 -0
- package/dist/security/scanner.js.map +1 -0
- package/dist/security/score.d.ts +150 -0
- package/dist/security/score.d.ts.map +1 -0
- package/dist/security/score.js +983 -0
- package/dist/security/score.js.map +1 -0
- package/dist/security/test-security.d.ts +22 -0
- package/dist/security/test-security.d.ts.map +1 -0
- package/dist/security/test-security.js +154 -0
- package/dist/security/test-security.js.map +1 -0
- package/dist/security/threatDetector.d.ts +39 -0
- package/dist/security/threatDetector.d.ts.map +1 -0
- package/dist/security/threatDetector.js +354 -0
- package/dist/security/threatDetector.js.map +1 -0
- package/dist/security/validation.d.ts +69 -0
- package/dist/security/validation.d.ts.map +1 -0
- package/dist/security/validation.js +286 -0
- package/dist/security/validation.js.map +1 -0
- package/dist/server/api/clientsRoute.d.ts +9 -0
- package/dist/server/api/clientsRoute.d.ts.map +1 -0
- package/dist/server/api/clientsRoute.js +71 -0
- package/dist/server/api/clientsRoute.js.map +1 -0
- package/dist/server/api/endpointsRoute.d.ts +8 -0
- package/dist/server/api/endpointsRoute.d.ts.map +1 -0
- package/dist/server/api/endpointsRoute.js +76 -0
- package/dist/server/api/endpointsRoute.js.map +1 -0
- package/dist/server/api/graphql.d.ts +9 -0
- package/dist/server/api/graphql.d.ts.map +1 -0
- package/dist/server/api/graphql.js +180 -0
- package/dist/server/api/graphql.js.map +1 -0
- package/dist/server/errors.d.ts +19 -0
- package/dist/server/errors.d.ts.map +1 -0
- package/dist/server/errors.js +42 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +24 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/kvStore.d.ts +27 -0
- package/dist/server/kvStore.d.ts.map +1 -0
- package/dist/server/kvStore.js +128 -0
- package/dist/server/kvStore.js.map +1 -0
- package/dist/server/runtimeSecurity.d.ts +28 -0
- package/dist/server/runtimeSecurity.d.ts.map +1 -0
- package/dist/server/runtimeSecurity.js +85 -0
- package/dist/server/runtimeSecurity.js.map +1 -0
- package/dist/server/types.d.ts +53 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +8 -0
- package/dist/server/types.js.map +1 -0
- package/dist/types/executionContext.d.ts +16 -0
- package/dist/types/executionContext.d.ts.map +1 -0
- package/dist/types/executionContext.js +3 -0
- package/dist/types/executionContext.js.map +1 -0
- package/package.json +77 -0
- package/src/agents/agentRegistry.ts +272 -0
- package/src/agents/image-agent.yaml +86 -0
- package/src/agents/joker-agent.yaml +47 -0
- package/src/agents/translator-agent.yaml +80 -0
- package/src/audit/auditTrail.ts +134 -0
- package/src/compliance/gdprEngine.ts +209 -0
- package/src/compliance/lgpdEngine.ts +268 -0
- package/src/config.ts +179 -0
- package/src/errors.ts +35 -0
- package/src/firebase/tenantManager.ts +443 -0
- package/src/index.ts +125 -0
- package/src/integration/secure-yaml-runtime.ts +341 -0
- package/src/parser/secure-yaml-parser.ts +273 -0
- package/src/performance/autoscaling.ts +495 -0
- package/src/performance/benchmark.ts +644 -0
- package/src/performance/index.ts +34 -0
- package/src/performance/monitor.ts +469 -0
- package/src/performance/streaming.ts +317 -0
- package/src/runtime/audit.ts +907 -0
- package/src/runtime/declarativeAgentRuntime.ts +836 -0
- package/src/runtime/isolatedRuntime.ts +572 -0
- package/src/runtime/schemaCompiler.ts +228 -0
- package/src/runtime/simpleRuntime.ts +201 -0
- package/src/security/dashboard.ts +462 -0
- package/src/security/hardening.ts +560 -0
- package/src/security/index.ts +439 -0
- package/src/security/monitor.ts +490 -0
- package/src/security/scanner.ts +368 -0
- package/src/security/score.ts +1138 -0
- package/src/security/threatDetector.ts +481 -0
- package/src/security/validation.ts +365 -0
- package/src/server/api/clientsRoute.ts +92 -0
- package/src/server/api/endpointsRoute.ts +97 -0
- package/src/server/api/graphql.ts +249 -0
- package/src/server/errors.ts +38 -0
- package/src/server/index.ts +6 -0
- package/src/server/kvStore.ts +152 -0
- package/src/server/runtimeSecurity.ts +102 -0
- package/src/server/types.ts +60 -0
- package/src/types/executionContext.ts +16 -0
- package/tools/seed.ts +365 -0
- package/tools/test-endpoints.ts +174 -0
|
@@ -0,0 +1,1138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security score calculator for YAML parsing
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Classe interna para implementação
|
|
6
|
+
class SecurityScoreImpl implements SecurityScoreCalculator {
|
|
7
|
+
private vulnerabilities: SecurityVulnerability[] = [];
|
|
8
|
+
private hardeningFeatures: HardeningFeature[] = [];
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
// State é inicializado em resetState()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Calcula o score de segurança completo
|
|
16
|
+
*/
|
|
17
|
+
public calculate(obj: any): SecurityScoreResult {
|
|
18
|
+
this.resetState();
|
|
19
|
+
|
|
20
|
+
// Análise de vulnerabilidades
|
|
21
|
+
this.analyzeVulnerabilities(obj);
|
|
22
|
+
|
|
23
|
+
// Análise de hardening
|
|
24
|
+
this.analyzeHardening(obj);
|
|
25
|
+
|
|
26
|
+
// Cálculo do score final
|
|
27
|
+
const score = this.calculateFinalScore();
|
|
28
|
+
const grade = this.calculateGrade(score);
|
|
29
|
+
const category = this.calculateCategory(grade);
|
|
30
|
+
const riskLevel = this.calculateRiskLevel(score);
|
|
31
|
+
const recommendations = this.getRecommendations(score);
|
|
32
|
+
const confidence = this.calculateConfidence();
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
score,
|
|
36
|
+
grade,
|
|
37
|
+
category,
|
|
38
|
+
vulnerabilities: [...this.vulnerabilities],
|
|
39
|
+
hardeningApplied: [...this.hardeningFeatures],
|
|
40
|
+
recommendations,
|
|
41
|
+
riskLevel,
|
|
42
|
+
confidence
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Analisa vulnerabilidades no objeto
|
|
48
|
+
*/
|
|
49
|
+
private analyzeVulnerabilities(obj: any): void {
|
|
50
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Análise de XSS e Code Injection
|
|
55
|
+
this.analyzeCodeInjection(obj);
|
|
56
|
+
|
|
57
|
+
// Análise de Circular References
|
|
58
|
+
this.analyzeCircularReferences(obj);
|
|
59
|
+
|
|
60
|
+
// Análise de Deep Nesting
|
|
61
|
+
this.analyzeDeepNesting(obj);
|
|
62
|
+
|
|
63
|
+
// Análise de Tamanho e Oversized
|
|
64
|
+
this.analyzeSizeVulnerabilities(obj);
|
|
65
|
+
|
|
66
|
+
// Análise de Conteúdo Suspeito
|
|
67
|
+
this.analyzeMaliciousContent(obj);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Analisa injeção de código
|
|
72
|
+
*/
|
|
73
|
+
private analyzeCodeInjection(obj: any, prefix = 'root'): void {
|
|
74
|
+
const deepAnalyze = (current: any, path: string) => {
|
|
75
|
+
if (typeof current === 'string') {
|
|
76
|
+
// Padrões de XSS
|
|
77
|
+
const xssPatterns = [
|
|
78
|
+
/<script[^>]*>/i,
|
|
79
|
+
/javascript:/i,
|
|
80
|
+
/on\w+\s*=/i,
|
|
81
|
+
/eval\s*\(/i,
|
|
82
|
+
/expression\s*\(/i,
|
|
83
|
+
/data:text\/html/i
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
for (const pattern of xssPatterns) {
|
|
87
|
+
if (pattern.test(current)) {
|
|
88
|
+
this.addVulnerability({
|
|
89
|
+
id: `XSS_${path}_${Date.now()}`,
|
|
90
|
+
type: 'XSS',
|
|
91
|
+
severity: 'high',
|
|
92
|
+
description: `Possível XSS detectado no caminho ${path}`,
|
|
93
|
+
path,
|
|
94
|
+
remediation: 'Escapar caracteres HTML e remover scripts',
|
|
95
|
+
cweId: 'CWE-79'
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Padrões de Template Injection
|
|
102
|
+
const templatePattern = /\$\{.*\}/;
|
|
103
|
+
if (templatePattern.test(current)) {
|
|
104
|
+
this.addVulnerability({
|
|
105
|
+
id: `TEMPLATE_${path}_${Date.now()}`,
|
|
106
|
+
type: 'TEMPLATE_INJECTION',
|
|
107
|
+
severity: 'medium',
|
|
108
|
+
description: `Possível template injection no caminho ${path}`,
|
|
109
|
+
path,
|
|
110
|
+
remediation: 'Validar e sanitizar strings de template',
|
|
111
|
+
cweId: 'CWE-1336'
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Padrões de Credential Leak
|
|
116
|
+
const credentialPattern = /(password|api_key|secret|token)\s*[:=]\s*["']?[\w\-]+["']?/i;
|
|
117
|
+
if (credentialPattern.test(current)) {
|
|
118
|
+
this.addVulnerability({
|
|
119
|
+
id: `CREDENTIAL_${path}_${Date.now()}`,
|
|
120
|
+
type: 'CREDENTIAL_LEAK',
|
|
121
|
+
severity: 'medium',
|
|
122
|
+
description: `Possível exposição de credenciais no caminho ${path}`,
|
|
123
|
+
path,
|
|
124
|
+
remediation: 'Remover ou mascarar informações sensíveis',
|
|
125
|
+
cweId: 'CWE-256'
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Recursivo para objetos aninhados
|
|
131
|
+
if (typeof current === 'object' && current !== null) {
|
|
132
|
+
if (Array.isArray(current)) {
|
|
133
|
+
current.forEach((item, index) => {
|
|
134
|
+
deepAnalyze(item, `${path}[${index}]`);
|
|
135
|
+
});
|
|
136
|
+
} else {
|
|
137
|
+
for (const [key, value] of Object.entries(current)) {
|
|
138
|
+
deepAnalyze(value, `${path}.${key}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
deepAnalyze(obj, prefix);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Analisa referências circulares
|
|
149
|
+
*/
|
|
150
|
+
private analyzeCircularReferences(obj: any): void {
|
|
151
|
+
try {
|
|
152
|
+
const circularDetector = new WeakSet();
|
|
153
|
+
this.detectCircularRecursive(obj, circularDetector, 'root');
|
|
154
|
+
} catch (error) {
|
|
155
|
+
this.addVulnerability({
|
|
156
|
+
id: `CIRCULAR_${Date.now()}`,
|
|
157
|
+
type: 'CIRCULAR_REFERENCE',
|
|
158
|
+
severity: 'high',
|
|
159
|
+
description: 'Referência circular detectada na estrutura',
|
|
160
|
+
path: 'root',
|
|
161
|
+
remediation: 'Remover referências circulares na estrutura YAML',
|
|
162
|
+
cweId: 'CWE-835'
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Detecta referências circulares recursivamente
|
|
169
|
+
*/
|
|
170
|
+
private detectCircularRecursive(obj: any, visited: WeakSet<any>, path: string): void {
|
|
171
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (visited.has(obj)) {
|
|
176
|
+
throw new Error(`Circular reference detected at ${path}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
visited.add(obj);
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
183
|
+
if (typeof value === 'object' && value !== null) {
|
|
184
|
+
this.detectCircularRecursive(value, visited, `${path}.${key}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} finally {
|
|
188
|
+
visited.delete(obj);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Analisa deep nesting
|
|
194
|
+
*/
|
|
195
|
+
private analyzeDeepNesting(obj: any): void {
|
|
196
|
+
const maxDepth = this.calculateMaxDepth(obj);
|
|
197
|
+
if (maxDepth > 1000) {
|
|
198
|
+
this.addVulnerability({
|
|
199
|
+
id: `DEEP_NESTING_${Date.now()}`,
|
|
200
|
+
type: 'DEEP_NESTING',
|
|
201
|
+
severity: 'medium',
|
|
202
|
+
description: `Profundidade excessiva de aninhamento: ${maxDepth} níveis`,
|
|
203
|
+
path: 'root',
|
|
204
|
+
remediation: 'Reduzir níveis de aninhamento para menos de 1000'
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Calcula profundidade máxima
|
|
211
|
+
*/
|
|
212
|
+
private calculateMaxDepth(obj: any, depth = 0): number {
|
|
213
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
214
|
+
return depth;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let maxDepth = depth;
|
|
218
|
+
for (const value of Object.values(obj)) {
|
|
219
|
+
maxDepth = Math.max(maxDepth, this.calculateMaxDepth(value, depth + 1));
|
|
220
|
+
}
|
|
221
|
+
return maxDepth;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Analisa vulnerabilidades de tamanho
|
|
226
|
+
*/
|
|
227
|
+
private analyzeSizeVulnerabilities(obj: any): void {
|
|
228
|
+
const totalSize = this.calculateObjectSize(obj);
|
|
229
|
+
|
|
230
|
+
if (totalSize > 100 * 1024 * 1024) { // 100MB
|
|
231
|
+
this.addVulnerability({
|
|
232
|
+
id: `OVERSIZED_${Date.now()}`,
|
|
233
|
+
type: 'OVERSIZED_PAYLOAD',
|
|
234
|
+
severity: 'high',
|
|
235
|
+
description: `Payload muito grande: ${(totalSize / (1024 * 1024)).toFixed(2)}MB`,
|
|
236
|
+
path: 'root',
|
|
237
|
+
remediation: 'Reduzir tamanho do payload para menos de 100MB'
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Calcula tamanho aproximado do objeto em bytes
|
|
244
|
+
*/
|
|
245
|
+
private calculateObjectSize(obj: any): number {
|
|
246
|
+
try {
|
|
247
|
+
return JSON.stringify(obj).length * 2; // Aproximação básica UTF-16
|
|
248
|
+
} catch {
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Analisa conteúdo malicioso
|
|
255
|
+
*/
|
|
256
|
+
private analyzeMaliciousContent(obj: any): void {
|
|
257
|
+
const maliciousPatterns = [
|
|
258
|
+
{ pattern: /cmd\.exe|powershell|bash/i, type: 'COMMAND_INJECTION' as const, severity: 'critical' as const },
|
|
259
|
+
{ pattern: /SELECT\s+\*|INSERT\s+INTO|UPDATE\s+.*SET|DELETE\s+FROM/i, type: 'SQL_INJECTION' as const, severity: 'critical' as const },
|
|
260
|
+
{ pattern: /union.*select|'.+'\s*=|'.*\bor\b/i, type: 'SQL_INJECTION' as const, severity: 'critical' as const },
|
|
261
|
+
{ pattern: /<\?xml.*encoding/i, type: 'XXE' as const, severity: 'high' as const }
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
const deepAnalyze = (current: any, path: string) => {
|
|
265
|
+
if (typeof current === 'string') {
|
|
266
|
+
for (const rule of maliciousPatterns) {
|
|
267
|
+
if (rule.pattern.test(current)) {
|
|
268
|
+
this.addVulnerability({
|
|
269
|
+
id: `${rule.type}_${path}_${Date.now()}`,
|
|
270
|
+
type: rule.type,
|
|
271
|
+
severity: rule.severity,
|
|
272
|
+
description: `Possível ${rule.type} detectado no caminho ${path}`,
|
|
273
|
+
path,
|
|
274
|
+
remediation: `Filtrar padrões de ${rule.type}`,
|
|
275
|
+
cweId: this.getCweForVulnerability(rule.type)
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (typeof current === 'object' && current !== null) {
|
|
282
|
+
for (const [key, value] of Object.entries(current)) {
|
|
283
|
+
deepAnalyze(value, `${path}.${key}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
deepAnalyze(obj, 'root');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Analisa hardening implementado
|
|
293
|
+
*/
|
|
294
|
+
private analyzeHardening(obj: any): void {
|
|
295
|
+
// Falha-safe Schema aplicado
|
|
296
|
+
this.addHardeningFeature({
|
|
297
|
+
name: 'FAILSAFE_SCHEMA',
|
|
298
|
+
status: 'applied',
|
|
299
|
+
effectiveness: 100,
|
|
300
|
+
description: 'Schema fail-safe aplicado para máxima segurança'
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Detecção de referências circulares
|
|
304
|
+
this.addHardeningFeature({
|
|
305
|
+
name: 'CIRCULAR_REFERENCE_DETECTION',
|
|
306
|
+
status: 'applied',
|
|
307
|
+
effectiveness: 85,
|
|
308
|
+
description: 'Detecção e prevenção de referências circulares'
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Limites de tamanho
|
|
312
|
+
this.addHardeningFeature({
|
|
313
|
+
name: 'SIZE_LIMITS',
|
|
314
|
+
status: 'applied',
|
|
315
|
+
effectiveness: 90,
|
|
316
|
+
description: 'Limites de tamanho implementados para prevenir DoS'
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Inspeção de conteúdo
|
|
320
|
+
this.addHardeningFeature({
|
|
321
|
+
name: 'CONTENT_INSPECTION',
|
|
322
|
+
status: 'partial',
|
|
323
|
+
effectiveness: 70,
|
|
324
|
+
description: 'Inspeção básica de conteúdo para padrões maliciosos'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// Validação estrutural
|
|
328
|
+
this.addHardeningFeature({
|
|
329
|
+
name: 'STRUCTURE_VALIDATION',
|
|
330
|
+
status: 'applied',
|
|
331
|
+
effectiveness: 95,
|
|
332
|
+
description: 'Validação rigorosa da estrutura do objeto'
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Adiciona uma vulnerabilidade encontrada
|
|
338
|
+
*/
|
|
339
|
+
private addVulnerability(vulnerability: SecurityVulnerability): void {
|
|
340
|
+
this.vulnerabilities.push({
|
|
341
|
+
...vulnerability,
|
|
342
|
+
cvssScore: this.estimateCvssScore(vulnerability.severity)
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Adiciona uma feature de hardening
|
|
348
|
+
*/
|
|
349
|
+
private addHardeningFeature(feature: HardeningFeature): void {
|
|
350
|
+
this.hardeningFeatures.push(feature);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Estima score CVSS baseado na severidade
|
|
355
|
+
*/
|
|
356
|
+
private estimateCvssScore(severity: string): number {
|
|
357
|
+
switch (severity) {
|
|
358
|
+
case 'critical': return 9.5;
|
|
359
|
+
case 'high': return 7.5;
|
|
360
|
+
case 'medium': return 5.0;
|
|
361
|
+
case 'low': return 2.5;
|
|
362
|
+
default: return 3.0;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Calcula o score final de segurança
|
|
368
|
+
*/
|
|
369
|
+
private calculateFinalScore(): number {
|
|
370
|
+
// Calcula score baseado em vulnerabilidades
|
|
371
|
+
let vulnerabilityScore = 100;
|
|
372
|
+
for (const vuln of this.vulnerabilities) {
|
|
373
|
+
vulnerabilityScore -= this.impactForVulnerability(vuln.severity);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Adiciona pontos pelas features de hardening
|
|
377
|
+
let hardeningScore = 0;
|
|
378
|
+
for (const feature of this.hardeningFeatures) {
|
|
379
|
+
if (feature.status === 'applied') {
|
|
380
|
+
hardeningScore += feature.effectiveness;
|
|
381
|
+
} else if (feature.status === 'partial') {
|
|
382
|
+
hardeningScore += feature.effectiveness * 0.5;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Score final (mínimo 0, máximo 100)
|
|
387
|
+
vulnerabilityScore = Math.max(0, vulnerabilityScore);
|
|
388
|
+
hardeningScore = Math.min(100, hardeningScore);
|
|
389
|
+
|
|
390
|
+
// Média ponderada: 70% da proteção base + 30% do hardening
|
|
391
|
+
return Math.round((vulnerabilityScore * 0.7) + (hardeningScore * 0.3));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Calcula impacto de uma vulnerabilidade
|
|
396
|
+
*/
|
|
397
|
+
private impactForVulnerability(severity: string): number {
|
|
398
|
+
switch (severity) {
|
|
399
|
+
case 'critical': return 30;
|
|
400
|
+
case 'high': return 20;
|
|
401
|
+
case 'medium': return 10;
|
|
402
|
+
case 'low': return 5;
|
|
403
|
+
default: return 8;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Calcula o grau baseado no score
|
|
409
|
+
*/
|
|
410
|
+
private calculateGrade(score: number): SecurityGrade {
|
|
411
|
+
if (score >= 90) return 'A';
|
|
412
|
+
if (score >= 80) return 'B';
|
|
413
|
+
if (score >= 70) return 'C';
|
|
414
|
+
if (score >= 60) return 'D';
|
|
415
|
+
return 'F';
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Calcula a categoria baseada no grau
|
|
420
|
+
*/
|
|
421
|
+
private calculateCategory(grade: SecurityGrade): SecurityCategory {
|
|
422
|
+
switch (grade) {
|
|
423
|
+
case 'A': return 'EXCEPTIONAL';
|
|
424
|
+
case 'B': return 'GOOD';
|
|
425
|
+
case 'C': return 'ACCEPTABLE';
|
|
426
|
+
case 'D': return 'LIMITED';
|
|
427
|
+
case 'F': return 'INSECURE';
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Calcula o nível de risco baseado no score
|
|
433
|
+
*/
|
|
434
|
+
private calculateRiskLevel(score: number): RiskLevel {
|
|
435
|
+
if (score >= 80) return 'LOW';
|
|
436
|
+
if (score >= 60) return 'MEDIUM';
|
|
437
|
+
if (score >= 40) return 'HIGH';
|
|
438
|
+
return 'CRITICAL';
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Obtém recomendações baseadas no score
|
|
443
|
+
*/
|
|
444
|
+
public getRecommendations(score: number): string[] {
|
|
445
|
+
const recommendations: string[] = [];
|
|
446
|
+
|
|
447
|
+
if (score < 90) {
|
|
448
|
+
recommendations.push('Implementar schema de segurança mais rigoroso (FAILSAFE_SCHEMA)');
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (score < 80) {
|
|
452
|
+
recommendations.push('Adicionar detecção de referências circulares');
|
|
453
|
+
recommendations.push('Implementar limites de tamanho para strings e objetos');
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (score < 70) {
|
|
457
|
+
recommendations.push('Adicionar inspeção de conteúdo para padrões maliciosos');
|
|
458
|
+
recommendations.push('Implementar validação de profundidade máxima');
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (score < 60) {
|
|
462
|
+
recommendations.push('Adicionar sandbox de execução segura');
|
|
463
|
+
recommendations.push('Implementar rate limiting e throttling');
|
|
464
|
+
recommendations.push('Adicionar logging detalhado de eventos de segurança');
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (score < 50) {
|
|
468
|
+
recommendations.push('Considerar reescrita completa com foco em segurança');
|
|
469
|
+
recommendations.push('Implementar múltiplas camadas de validação');
|
|
470
|
+
recommendations.push('Adicionar scanning de vulnerabilidades');
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return recommendations;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Calcula a confiança no resultado
|
|
478
|
+
*/
|
|
479
|
+
public calculateConfidence(): number {
|
|
480
|
+
// Calcula confiança baseada na profundidade da análise
|
|
481
|
+
const vulnerabilityFactor = this.vulnerabilities.length > 0 ? Math.min(100, this.vulnerabilities.length * 20) : 70;
|
|
482
|
+
const hardeningFactor = this.hardeningFeatures.length * 15;
|
|
483
|
+
return Math.min(100, vulnerabilityFactor + hardeningFactor);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Calcula score de componente específico
|
|
488
|
+
*/
|
|
489
|
+
public calculateComponentScore(component: string): number {
|
|
490
|
+
// Score base para diferentes componentes
|
|
491
|
+
const componentScores: Record<string, number> = {
|
|
492
|
+
'validation': 85,
|
|
493
|
+
'parsing': 75,
|
|
494
|
+
'hardening': 90,
|
|
495
|
+
'encryption': 95,
|
|
496
|
+
'authentication': 90
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
return componentScores[component.toLowerCase()] || 70;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Obtém CWE ID para tipos de vulnerabilidade
|
|
504
|
+
*/
|
|
505
|
+
private getCweForVulnerability(type: string): string {
|
|
506
|
+
const cweMap: Record<string, string> = {
|
|
507
|
+
'XSS': 'CWE-79',
|
|
508
|
+
'SQL_INJECTION': 'CWE-89',
|
|
509
|
+
'CODE_INJECTION': 'CWE-94',
|
|
510
|
+
'TEMPLATE_INJECTION': 'CWE-1336',
|
|
511
|
+
'PATH_TRAVERSAL': 'CWE-22',
|
|
512
|
+
'XXE': 'CWE-611',
|
|
513
|
+
'LDAP_INJECTION': 'CWE-90',
|
|
514
|
+
'COMMAND_INJECTION': 'CWE-78',
|
|
515
|
+
'INSECURE_DESERIALIZATION': 'CWE-502',
|
|
516
|
+
'CIRCULAR_REFERENCE': 'CWE-835',
|
|
517
|
+
'DEEP_NESTING': 'CWE-674',
|
|
518
|
+
'OVERSIZED_PAYLOAD': 'CWE-400',
|
|
519
|
+
'CREDENTIAL_LEAK': 'CWE-256',
|
|
520
|
+
'PII_EXPOSURE': 'CWE-359',
|
|
521
|
+
'MALICIOUS_CONTENT': 'CWE-434'
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
return cweMap[type] || 'CWE-20';
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Reinicia o estado do calculador
|
|
529
|
+
*/
|
|
530
|
+
private resetState(): void {
|
|
531
|
+
this.vulnerabilities = [];
|
|
532
|
+
this.hardeningFeatures = [];
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export interface SecurityScoreResult {
|
|
537
|
+
score: number; // 0-100
|
|
538
|
+
grade: SecurityGrade;
|
|
539
|
+
category: SecurityCategory;
|
|
540
|
+
vulnerabilities: SecurityVulnerability[];
|
|
541
|
+
hardeningApplied: HardeningFeature[];
|
|
542
|
+
recommendations: string[];
|
|
543
|
+
riskLevel: RiskLevel;
|
|
544
|
+
confidence: number; // 0-100
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export type SecurityGrade = 'A' | 'B' | 'C' | 'D' | 'F';
|
|
548
|
+
export type SecurityCategory = 'EXCEPTIONAL' | 'GOOD' | 'ACCEPTABLE' | 'LIMITED' | 'INSECURE';
|
|
549
|
+
export type RiskLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
550
|
+
export interface SecurityVulnerability {
|
|
551
|
+
id: string;
|
|
552
|
+
type: VulnerabilityType;
|
|
553
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
554
|
+
description: string;
|
|
555
|
+
path: string;
|
|
556
|
+
remediation: string;
|
|
557
|
+
cweId?: string;
|
|
558
|
+
cvssScore?: number;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export interface HardeningFeature {
|
|
562
|
+
name: string;
|
|
563
|
+
status: 'applied' | 'partial' | 'not_applied';
|
|
564
|
+
effectiveness: number; // 0-100
|
|
565
|
+
description: string;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export type VulnerabilityType =
|
|
569
|
+
| 'XSS'
|
|
570
|
+
| 'SQL_INJECTION'
|
|
571
|
+
| 'CODE_INJECTION'
|
|
572
|
+
| 'TEMPLATE_INJECTION'
|
|
573
|
+
| 'PATH_TRAVERSAL'
|
|
574
|
+
| 'XXE'
|
|
575
|
+
| 'LDAP_INJECTION'
|
|
576
|
+
| 'COMMAND_INJECTION'
|
|
577
|
+
| 'INSECURE_DESERIALIZATION'
|
|
578
|
+
| 'CIRCULAR_REFERENCE'
|
|
579
|
+
| 'DEEP_NESTING'
|
|
580
|
+
| 'OVERSIZED_PAYLOAD'
|
|
581
|
+
| 'CREDENTIAL_LEAK'
|
|
582
|
+
| 'PII_EXPOSURE'
|
|
583
|
+
| 'MALICIOUS_CONTENT';
|
|
584
|
+
|
|
585
|
+
export interface SecurityScoreCalculator {
|
|
586
|
+
calculate(obj: any): SecurityScoreResult;
|
|
587
|
+
calculateComponentScore(component: string): number;
|
|
588
|
+
getRecommendations(score: number): string[];
|
|
589
|
+
calculateConfidence(result: SecurityScoreResult): number;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
class SecurityScore implements SecurityScoreCalculator {
|
|
593
|
+
private vulnerabilities: SecurityVulnerability[] = [];
|
|
594
|
+
private hardeningFeatures: HardeningFeature[] = [];
|
|
595
|
+
|
|
596
|
+
constructor() {
|
|
597
|
+
// State é inicializado em resetState()
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Calcula o score de segurança completo
|
|
602
|
+
*/
|
|
603
|
+
public calculate(obj: any): SecurityScoreResult {
|
|
604
|
+
this.resetState();
|
|
605
|
+
|
|
606
|
+
// Análise de vulnerabilidades
|
|
607
|
+
this.analyzeVulnerabilities(obj);
|
|
608
|
+
|
|
609
|
+
// Análise de hardening
|
|
610
|
+
this.analyzeHardening(obj);
|
|
611
|
+
|
|
612
|
+
// Cálculo do score final
|
|
613
|
+
const score = this.calculateFinalScore();
|
|
614
|
+
const grade = this.calculateGrade(score);
|
|
615
|
+
const category = this.calculateCategory(grade);
|
|
616
|
+
const riskLevel = this.calculateRiskLevel(score);
|
|
617
|
+
const recommendations = this.getRecommendations(score);
|
|
618
|
+
const confidence = this.calculateConfidence();
|
|
619
|
+
|
|
620
|
+
return {
|
|
621
|
+
score,
|
|
622
|
+
grade,
|
|
623
|
+
category,
|
|
624
|
+
vulnerabilities: [...this.vulnerabilities],
|
|
625
|
+
hardeningApplied: [...this.hardeningFeatures],
|
|
626
|
+
recommendations,
|
|
627
|
+
riskLevel,
|
|
628
|
+
confidence
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Analisa vulnerabilidades no objeto
|
|
634
|
+
*/
|
|
635
|
+
private analyzeVulnerabilities(obj: any): void {
|
|
636
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Análise de XSS e Code Injection
|
|
641
|
+
this.analyzeCodeInjection(obj);
|
|
642
|
+
|
|
643
|
+
// Análise de Circular References
|
|
644
|
+
this.analyzeCircularReferences(obj);
|
|
645
|
+
|
|
646
|
+
// Análise de Deep Nesting
|
|
647
|
+
this.analyzeDeepNesting(obj);
|
|
648
|
+
|
|
649
|
+
// Análise de Tamanho e Oversized
|
|
650
|
+
this.analyzeSizeVulnerabilities(obj);
|
|
651
|
+
|
|
652
|
+
// Análise de Conteúdo Suspeito
|
|
653
|
+
this.analyzeMaliciousContent(obj);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Analisa injeção de código
|
|
658
|
+
*/
|
|
659
|
+
private analyzeCodeInjection(obj: any, prefix = 'root'): void {
|
|
660
|
+
const deepAnalyze = (current: any, path: string) => {
|
|
661
|
+
if (typeof current === 'string') {
|
|
662
|
+
// Padrões de XSS
|
|
663
|
+
const xssPatterns = [
|
|
664
|
+
/<script[^>]*>/i,
|
|
665
|
+
/javascript:/i,
|
|
666
|
+
/on\w+\s*=/i,
|
|
667
|
+
/eval\s*\(/i,
|
|
668
|
+
/expression\s*\(/i,
|
|
669
|
+
/data:text\/html/i
|
|
670
|
+
];
|
|
671
|
+
|
|
672
|
+
for (const pattern of xssPatterns) {
|
|
673
|
+
if (pattern.test(current)) {
|
|
674
|
+
this.addVulnerability({
|
|
675
|
+
id: `XSS_${path}_${Date.now()}`,
|
|
676
|
+
type: 'XSS',
|
|
677
|
+
severity: 'high',
|
|
678
|
+
description: `Possível XSS detectado no caminho ${path}`,
|
|
679
|
+
path,
|
|
680
|
+
remediation: 'Escapar caracteres HTML e remover scripts',
|
|
681
|
+
cweId: 'CWE-79'
|
|
682
|
+
});
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Padrões de Template Injection
|
|
688
|
+
const templatePattern = /\$\{.*\}/;
|
|
689
|
+
if (templatePattern.test(current)) {
|
|
690
|
+
this.addVulnerability({
|
|
691
|
+
id: `TEMPLATE_${path}_${Date.now()}`,
|
|
692
|
+
type: 'TEMPLATE_INJECTION',
|
|
693
|
+
severity: 'medium',
|
|
694
|
+
description: `Possível template injection no caminho ${path}`,
|
|
695
|
+
path,
|
|
696
|
+
remediation: 'Validar e sanitizar strings de template',
|
|
697
|
+
cweId: 'CWE-1336'
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Padrões de Credential Leak
|
|
702
|
+
const credentialPattern = /(password|api_key|secret|token)\s*[:=]\s*["']?[\w\-]+["']?/i;
|
|
703
|
+
if (credentialPattern.test(current)) {
|
|
704
|
+
this.addVulnerability({
|
|
705
|
+
id: `CREDENTIAL_${path}_${Date.now()}`,
|
|
706
|
+
type: 'CREDENTIAL_LEAK',
|
|
707
|
+
severity: 'medium',
|
|
708
|
+
description: `Possível exposição de credenciais no caminho ${path}`,
|
|
709
|
+
path,
|
|
710
|
+
remediation: 'Remover ou mascarar informações sensíveis',
|
|
711
|
+
cweId: 'CWE-256'
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// Recursivo para objetos aninhados
|
|
717
|
+
if (typeof current === 'object' && current !== null) {
|
|
718
|
+
if (Array.isArray(current)) {
|
|
719
|
+
current.forEach((item, index) => {
|
|
720
|
+
deepAnalyze(item, `${path}[${index}]`);
|
|
721
|
+
});
|
|
722
|
+
} else {
|
|
723
|
+
for (const [key, value] of Object.entries(current)) {
|
|
724
|
+
deepAnalyze(value, `${path}.${key}`);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
deepAnalyze(obj, prefix);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Analisa referências circulares
|
|
735
|
+
*/
|
|
736
|
+
private analyzeCircularReferences(obj: any): void {
|
|
737
|
+
try {
|
|
738
|
+
const circularDetector = new WeakSet();
|
|
739
|
+
this.detectCircularRecursive(obj, circularDetector, 'root');
|
|
740
|
+
} catch (error) {
|
|
741
|
+
this.addVulnerability({
|
|
742
|
+
id: `CIRCULAR_${Date.now()}`,
|
|
743
|
+
type: 'CIRCULAR_REFERENCE',
|
|
744
|
+
severity: 'high',
|
|
745
|
+
description: 'Referência circular detectada na estrutura',
|
|
746
|
+
path: 'root',
|
|
747
|
+
remediation: 'Remover referências circulares na estrutura YAML',
|
|
748
|
+
cweId: 'CWE-835'
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Detecta referências circulares recursivamente
|
|
755
|
+
*/
|
|
756
|
+
private detectCircularRecursive(obj: any, visited: WeakSet<any>, path: string): void {
|
|
757
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (visited.has(obj)) {
|
|
762
|
+
throw new Error(`Circular reference detected at ${path}`);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
visited.add(obj);
|
|
766
|
+
|
|
767
|
+
try {
|
|
768
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
769
|
+
if (typeof value === 'object' && value !== null) {
|
|
770
|
+
this.detectCircularRecursive(value, visited, `${path}.${key}`);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
} finally {
|
|
774
|
+
visited.delete(obj);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Analisa deep nesting
|
|
780
|
+
*/
|
|
781
|
+
private analyzeDeepNesting(obj: any): void {
|
|
782
|
+
const maxDepth = this.calculateMaxDepth(obj);
|
|
783
|
+
if (maxDepth > 1000) {
|
|
784
|
+
this.addVulnerability({
|
|
785
|
+
id: `DEEP_NESTING_${Date.now()}`,
|
|
786
|
+
type: 'DEEP_NESTING',
|
|
787
|
+
severity: 'medium',
|
|
788
|
+
description: `Profundidade excessiva de aninhamento: ${maxDepth} níveis`,
|
|
789
|
+
path: 'root',
|
|
790
|
+
remediation: 'Reduzir níveis de aninhamento para menos de 1000'
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Calcula profundidade máxima
|
|
797
|
+
*/
|
|
798
|
+
private calculateMaxDepth(obj: any, depth = 0): number {
|
|
799
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
800
|
+
return depth;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
let maxDepth = depth;
|
|
804
|
+
for (const value of Object.values(obj)) {
|
|
805
|
+
maxDepth = Math.max(maxDepth, this.calculateMaxDepth(value, depth + 1));
|
|
806
|
+
}
|
|
807
|
+
return maxDepth;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Analisa vulnerabilidades de tamanho
|
|
812
|
+
*/
|
|
813
|
+
private analyzeSizeVulnerabilities(obj: any): void {
|
|
814
|
+
const totalSize = this.calculateObjectSize(obj);
|
|
815
|
+
|
|
816
|
+
if (totalSize > 100 * 1024 * 1024) { // 100MB
|
|
817
|
+
this.addVulnerability({
|
|
818
|
+
id: `OVERSIZED_${Date.now()}`,
|
|
819
|
+
type: 'OVERSIZED_PAYLOAD',
|
|
820
|
+
severity: 'high',
|
|
821
|
+
description: `Payload muito grande: ${(totalSize / (1024 * 1024)).toFixed(2)}MB`,
|
|
822
|
+
path: 'root',
|
|
823
|
+
remediation: 'Reduzir tamanho do payload para menos de 100MB'
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Calcula tamanho aproximado do objeto em bytes
|
|
830
|
+
*/
|
|
831
|
+
private calculateObjectSize(obj: any): number {
|
|
832
|
+
try {
|
|
833
|
+
return JSON.stringify(obj).length * 2; // Aproximação básica UTF-16
|
|
834
|
+
} catch {
|
|
835
|
+
return 0;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Analisa conteúdo malicioso
|
|
841
|
+
*/
|
|
842
|
+
private analyzeMaliciousContent(obj: any): void {
|
|
843
|
+
const maliciousPatterns = [
|
|
844
|
+
{ pattern: /cmd\.exe|powershell|bash/i, type: 'COMMAND_INJECTION' as const, severity: 'critical' as const },
|
|
845
|
+
{ pattern: /SELECT\s+\*|INSERT\s+INTO|UPDATE\s+.*SET|DELETE\s+FROM/i, type: 'SQL_INJECTION' as const, severity: 'critical' as const },
|
|
846
|
+
{ pattern: /union.*select|'.+'\s*=|'.*\bor\b/i, type: 'SQL_INJECTION' as const, severity: 'critical' as const },
|
|
847
|
+
{ pattern: /<\?xml.*encoding/i, type: 'XXE' as const, severity: 'high' as const }
|
|
848
|
+
];
|
|
849
|
+
|
|
850
|
+
const deepAnalyze = (current: any, path: string) => {
|
|
851
|
+
if (typeof current === 'string') {
|
|
852
|
+
for (const rule of maliciousPatterns) {
|
|
853
|
+
if (rule.pattern.test(current)) {
|
|
854
|
+
this.addVulnerability({
|
|
855
|
+
id: `${rule.type}_${path}_${Date.now()}`,
|
|
856
|
+
type: rule.type,
|
|
857
|
+
severity: rule.severity,
|
|
858
|
+
description: `Possível ${rule.type} detectado no caminho ${path}`,
|
|
859
|
+
path,
|
|
860
|
+
remediation: `Filtrar padrões de ${rule.type}`,
|
|
861
|
+
cweId: this.getCweForVulnerability(rule.type)
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
if (typeof current === 'object' && current !== null) {
|
|
868
|
+
for (const [key, value] of Object.entries(current)) {
|
|
869
|
+
deepAnalyze(value, `${path}.${key}`);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
deepAnalyze(obj, 'root');
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Analisa hardening implementado
|
|
879
|
+
*/
|
|
880
|
+
private analyzeHardening(obj: any): void {
|
|
881
|
+
// Falha-safe Schema aplicado
|
|
882
|
+
this.addHardeningFeature({
|
|
883
|
+
name: 'FAILSAFE_SCHEMA',
|
|
884
|
+
status: 'applied',
|
|
885
|
+
effectiveness: 100,
|
|
886
|
+
description: 'Schema fail-safe aplicado para máxima segurança'
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
// Detecção de referências circulares
|
|
890
|
+
this.addHardeningFeature({
|
|
891
|
+
name: 'CIRCULAR_REFERENCE_DETECTION',
|
|
892
|
+
status: 'applied',
|
|
893
|
+
effectiveness: 85,
|
|
894
|
+
description: 'Detecção e prevenção de referências circulares'
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
// Limites de tamanho
|
|
898
|
+
this.addHardeningFeature({
|
|
899
|
+
name: 'SIZE_LIMITS',
|
|
900
|
+
status: 'applied',
|
|
901
|
+
effectiveness: 90,
|
|
902
|
+
description: 'Limites de tamanho implementados para prevenir DoS'
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
// Inspeção de conteúdo
|
|
906
|
+
this.addHardeningFeature({
|
|
907
|
+
name: 'CONTENT_INSPECTION',
|
|
908
|
+
status: 'partial',
|
|
909
|
+
effectiveness: 70,
|
|
910
|
+
description: 'Inspeção básica de conteúdo para padrões maliciosos'
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
// Validação estrutural
|
|
914
|
+
this.addHardeningFeature({
|
|
915
|
+
name: 'STRUCTURE_VALIDATION',
|
|
916
|
+
status: 'applied',
|
|
917
|
+
effectiveness: 95,
|
|
918
|
+
description: 'Validação rigorosa da estrutura do objeto'
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Adiciona uma vulnerabilidade encontrada
|
|
924
|
+
*/
|
|
925
|
+
private addVulnerability(vulnerability: SecurityVulnerability): void {
|
|
926
|
+
this.vulnerabilities.push({
|
|
927
|
+
...vulnerability,
|
|
928
|
+
cvssScore: this.estimateCvssScore(vulnerability.severity)
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* Adiciona uma feature de hardening
|
|
934
|
+
*/
|
|
935
|
+
private addHardeningFeature(feature: HardeningFeature): void {
|
|
936
|
+
this.hardeningFeatures.push(feature);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* Estima score CVSS baseado na severidade
|
|
941
|
+
*/
|
|
942
|
+
private estimateCvssScore(severity: string): number {
|
|
943
|
+
switch (severity) {
|
|
944
|
+
case 'critical': return 9.5;
|
|
945
|
+
case 'high': return 7.5;
|
|
946
|
+
case 'medium': return 5.0;
|
|
947
|
+
case 'low': return 2.5;
|
|
948
|
+
default: return 3.0;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* Calcula o score final de segurança
|
|
954
|
+
*/
|
|
955
|
+
private calculateFinalScore(): number {
|
|
956
|
+
// Calcula score baseado em vulnerabilidades
|
|
957
|
+
let vulnerabilityScore = 100;
|
|
958
|
+
for (const vuln of this.vulnerabilities) {
|
|
959
|
+
vulnerabilityScore -= this.impactForVulnerability(vuln.severity);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// Adiciona pontos pelas features de hardening
|
|
963
|
+
let hardeningScore = 0;
|
|
964
|
+
for (const feature of this.hardeningFeatures) {
|
|
965
|
+
if (feature.status === 'applied') {
|
|
966
|
+
hardeningScore += feature.effectiveness;
|
|
967
|
+
} else if (feature.status === 'partial') {
|
|
968
|
+
hardeningScore += feature.effectiveness * 0.5;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// Score final (mínimo 0, máximo 100)
|
|
973
|
+
vulnerabilityScore = Math.max(0, vulnerabilityScore);
|
|
974
|
+
hardeningScore = Math.min(100, hardeningScore);
|
|
975
|
+
|
|
976
|
+
// Média ponderada: 70% da proteção base + 30% do hardening
|
|
977
|
+
return Math.round((vulnerabilityScore * 0.7) + (hardeningScore * 0.3));
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Calcula impacto de uma vulnerabilidade
|
|
982
|
+
*/
|
|
983
|
+
private impactForVulnerability(severity: string): number {
|
|
984
|
+
switch (severity) {
|
|
985
|
+
case 'critical': return 30;
|
|
986
|
+
case 'high': return 20;
|
|
987
|
+
case 'medium': return 10;
|
|
988
|
+
case 'low': return 5;
|
|
989
|
+
default: return 8;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* Calcula o grau baseado no score
|
|
995
|
+
*/
|
|
996
|
+
private calculateGrade(score: number): SecurityGrade {
|
|
997
|
+
if (score >= 90) return 'A';
|
|
998
|
+
if (score >= 80) return 'B';
|
|
999
|
+
if (score >= 70) return 'C';
|
|
1000
|
+
if (score >= 60) return 'D';
|
|
1001
|
+
return 'F';
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Calcula a categoria baseada no grau
|
|
1006
|
+
*/
|
|
1007
|
+
private calculateCategory(grade: SecurityGrade): SecurityCategory {
|
|
1008
|
+
switch (grade) {
|
|
1009
|
+
case 'A': return 'EXCEPTIONAL';
|
|
1010
|
+
case 'B': return 'GOOD';
|
|
1011
|
+
case 'C': return 'ACCEPTABLE';
|
|
1012
|
+
case 'D': return 'LIMITED';
|
|
1013
|
+
case 'F': return 'INSECURE';
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Calcula o nível de risco baseado no score
|
|
1019
|
+
*/
|
|
1020
|
+
private calculateRiskLevel(score: number): RiskLevel {
|
|
1021
|
+
if (score >= 80) return 'LOW';
|
|
1022
|
+
if (score >= 60) return 'MEDIUM';
|
|
1023
|
+
if (score >= 40) return 'HIGH';
|
|
1024
|
+
return 'CRITICAL';
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Obtém recomendações baseadas no score
|
|
1029
|
+
*/
|
|
1030
|
+
public getRecommendations(score: number): string[] {
|
|
1031
|
+
const recommendations: string[] = [];
|
|
1032
|
+
|
|
1033
|
+
if (score < 90) {
|
|
1034
|
+
recommendations.push('Implementar schema de segurança mais rigoroso (FAILSAFE_SCHEMA)');
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
if (score < 80) {
|
|
1038
|
+
recommendations.push('Adicionar detecção de referências circulares');
|
|
1039
|
+
recommendations.push('Implementar limites de tamanho para strings e objetos');
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
if (score < 70) {
|
|
1043
|
+
recommendations.push('Adicionar inspeção de conteúdo para padrões maliciosos');
|
|
1044
|
+
recommendations.push('Implementar validação de profundidade máxima');
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (score < 60) {
|
|
1048
|
+
recommendations.push('Adicionar sandbox de execução segura');
|
|
1049
|
+
recommendations.push('Implementar rate limiting e throttling');
|
|
1050
|
+
recommendations.push('Adicionar logging detalhado de eventos de segurança');
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
if (score < 50) {
|
|
1054
|
+
recommendations.push('Considerar reescrita completa com foco em segurança');
|
|
1055
|
+
recommendations.push('Implementar múltiplas camadas de validação');
|
|
1056
|
+
recommendations.push('Adicionar scanning de vulnerabilidades');
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
return recommendations;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Calcula a confiança no resultado
|
|
1064
|
+
*/
|
|
1065
|
+
public calculateConfidence(): number {
|
|
1066
|
+
// Calcula confiança baseada na profundidade da análise
|
|
1067
|
+
const vulnerabilityFactor = this.vulnerabilities.length > 0 ? Math.min(100, this.vulnerabilities.length * 20) : 70;
|
|
1068
|
+
const hardeningFactor = this.hardeningFeatures.length * 15;
|
|
1069
|
+
return Math.min(100, vulnerabilityFactor + hardeningFactor);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* Calcula score de componente específico
|
|
1074
|
+
*/
|
|
1075
|
+
public calculateComponentScore(component: string): number {
|
|
1076
|
+
// Score base para diferentes componentes
|
|
1077
|
+
const componentScores: Record<string, number> = {
|
|
1078
|
+
'validation': 85,
|
|
1079
|
+
'parsing': 75,
|
|
1080
|
+
'hardening': 90,
|
|
1081
|
+
'encryption': 95,
|
|
1082
|
+
'authentication': 90
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
return componentScores[component.toLowerCase()] || 70;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Obtém CWE ID para tipos de vulnerabilidade
|
|
1090
|
+
*/
|
|
1091
|
+
private getCweForVulnerability(type: string): string {
|
|
1092
|
+
const cweMap: Record<string, string> = {
|
|
1093
|
+
'XSS': 'CWE-79',
|
|
1094
|
+
'SQL_INJECTION': 'CWE-89',
|
|
1095
|
+
'CODE_INJECTION': 'CWE-94',
|
|
1096
|
+
'TEMPLATE_INJECTION': 'CWE-1336',
|
|
1097
|
+
'PATH_TRAVERSAL': 'CWE-22',
|
|
1098
|
+
'XXE': 'CWE-611',
|
|
1099
|
+
'LDAP_INJECTION': 'CWE-90',
|
|
1100
|
+
'COMMAND_INJECTION': 'CWE-78',
|
|
1101
|
+
'INSECURE_DESERIALIZATION': 'CWE-502',
|
|
1102
|
+
'CIRCULAR_REFERENCE': 'CWE-835',
|
|
1103
|
+
'DEEP_NESTING': 'CWE-674',
|
|
1104
|
+
'OVERSIZED_PAYLOAD': 'CWE-400',
|
|
1105
|
+
'CREDENTIAL_LEAK': 'CWE-256',
|
|
1106
|
+
'PII_EXPOSURE': 'CWE-359',
|
|
1107
|
+
'MALICIOUS_CONTENT': 'CWE-434'
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
return cweMap[type] || 'CWE-20';
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Reinicia o estado do calculador
|
|
1115
|
+
*/
|
|
1116
|
+
private resetState(): void {
|
|
1117
|
+
this.vulnerabilities = [];
|
|
1118
|
+
this.hardeningFeatures = [];
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* Função auxiliar para calcular segurança
|
|
1124
|
+
*/
|
|
1125
|
+
export function calculateSecurityScore(obj: any): SecurityScoreResult {
|
|
1126
|
+
const calculator = new SecurityScore();
|
|
1127
|
+
return calculator.calculate(obj);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Função auxiliar para obter recomendações
|
|
1132
|
+
*/
|
|
1133
|
+
export function getSecurityRecommendations(score: number): string[] {
|
|
1134
|
+
const calculator = new SecurityScore();
|
|
1135
|
+
return calculator.getRecommendations(score);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
export { SecurityScoreImpl as SecurityScore };
|