codeslick-cli 1.3.0 → 1.4.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 +50 -11
- package/dist/packages/cli/src/scanner/local-scanner.d.ts +2 -2
- package/dist/packages/cli/src/scanner/local-scanner.d.ts.map +1 -1
- package/dist/packages/cli/src/scanner/local-scanner.js +10 -1
- package/dist/packages/cli/src/scanner/local-scanner.js.map +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/credentials.js +1 -1
- package/dist/src/lib/analyzers/secrets/patterns/credentials.js.map +1 -1
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts +4 -0
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.d.ts.map +1 -1
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.js +48 -4
- package/dist/src/lib/analyzers/secrets/secrets-analyzer.js.map +1 -1
- package/dist/src/lib/analyzers/terraform/aws-checks.d.ts +71 -0
- package/dist/src/lib/analyzers/terraform/aws-checks.d.ts.map +1 -0
- package/dist/src/lib/analyzers/terraform/aws-checks.js +538 -0
- package/dist/src/lib/analyzers/terraform/aws-checks.js.map +1 -0
- package/dist/src/lib/analyzers/terraform/parser.d.ts +14 -0
- package/dist/src/lib/analyzers/terraform/parser.d.ts.map +1 -0
- package/dist/src/lib/analyzers/terraform/parser.js +237 -0
- package/dist/src/lib/analyzers/terraform/parser.js.map +1 -0
- package/dist/src/lib/analyzers/terraform/types.d.ts +70 -0
- package/dist/src/lib/analyzers/terraform/types.d.ts.map +1 -0
- package/dist/src/lib/analyzers/terraform/types.js +9 -0
- package/dist/src/lib/analyzers/terraform/types.js.map +1 -0
- package/dist/src/lib/analyzers/terraform-analyzer.d.ts +49 -0
- package/dist/src/lib/analyzers/terraform-analyzer.d.ts.map +1 -0
- package/dist/src/lib/analyzers/terraform-analyzer.js +140 -0
- package/dist/src/lib/analyzers/terraform-analyzer.js.map +1 -0
- package/dist/src/lib/analyzers/typescript/security-checks/type-security.d.ts.map +1 -1
- package/dist/src/lib/analyzers/typescript/security-checks/type-security.js +23 -8
- package/dist/src/lib/analyzers/typescript/security-checks/type-security.js.map +1 -1
- package/dist/src/lib/security/epss-service.d.ts.map +1 -1
- package/dist/src/lib/security/epss-service.js +64 -50
- package/dist/src/lib/security/epss-service.js.map +1 -1
- package/dist/src/lib/security/severity-scoring.d.ts.map +1 -1
- package/dist/src/lib/security/severity-scoring.js +116 -0
- package/dist/src/lib/security/severity-scoring.js.map +1 -1
- package/dist/src/lib/types/index.d.ts +1 -1
- package/dist/src/lib/types/index.d.ts.map +1 -1
- package/package.json +10 -7
- package/src/scanner/local-scanner.ts +13 -2
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Terraform HCL Parser
|
|
4
|
+
*
|
|
5
|
+
* WR3: IaC Scanning - Simple regex-based HCL parser
|
|
6
|
+
* Extracts resource blocks, attributes, and nested blocks from Terraform files
|
|
7
|
+
*
|
|
8
|
+
* MVP Approach: Regex-based parsing (fast, good enough for security checks)
|
|
9
|
+
* Future: Can swap for full HCL library if needed (no API changes required)
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.parseTerraform = parseTerraform;
|
|
13
|
+
exports.getAttribute = getAttribute;
|
|
14
|
+
exports.hasAttribute = hasAttribute;
|
|
15
|
+
function parseTerraform(code) {
|
|
16
|
+
const lines = code.split('\n');
|
|
17
|
+
const resources = [];
|
|
18
|
+
const dataBlocks = [];
|
|
19
|
+
const variables = [];
|
|
20
|
+
const outputs = [];
|
|
21
|
+
const locals = [];
|
|
22
|
+
const modules = [];
|
|
23
|
+
let i = 0;
|
|
24
|
+
while (i < lines.length) {
|
|
25
|
+
const line = lines[i].trim();
|
|
26
|
+
// Match resource blocks: resource "aws_s3_bucket" "my_bucket" {
|
|
27
|
+
const resourceMatch = line.match(/^resource\s+"([^"]+)"\s+"([^"]+)"\s*\{/);
|
|
28
|
+
if (resourceMatch) {
|
|
29
|
+
const block = parseBlock(lines, i, 'resource', [resourceMatch[1], resourceMatch[2]]);
|
|
30
|
+
const resource = {
|
|
31
|
+
...block,
|
|
32
|
+
resourceType: resourceMatch[1],
|
|
33
|
+
resourceName: resourceMatch[2],
|
|
34
|
+
provider: detectProvider(resourceMatch[1]),
|
|
35
|
+
};
|
|
36
|
+
resources.push(resource);
|
|
37
|
+
i = block.endLine + 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Match data blocks: data "aws_ami" "ubuntu" {
|
|
41
|
+
const dataMatch = line.match(/^data\s+"([^"]+)"\s+"([^"]+)"\s*\{/);
|
|
42
|
+
if (dataMatch) {
|
|
43
|
+
const block = parseBlock(lines, i, 'data', [dataMatch[1], dataMatch[2]]);
|
|
44
|
+
dataBlocks.push(block);
|
|
45
|
+
i = block.endLine + 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
// Match variable blocks: variable "instance_type" {
|
|
49
|
+
const variableMatch = line.match(/^variable\s+"([^"]+)"\s*\{/);
|
|
50
|
+
if (variableMatch) {
|
|
51
|
+
const block = parseBlock(lines, i, 'variable', [variableMatch[1]]);
|
|
52
|
+
variables.push(block);
|
|
53
|
+
i = block.endLine + 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Match output blocks: output "instance_ip" {
|
|
57
|
+
const outputMatch = line.match(/^output\s+"([^"]+)"\s*\{/);
|
|
58
|
+
if (outputMatch) {
|
|
59
|
+
const block = parseBlock(lines, i, 'output', [outputMatch[1]]);
|
|
60
|
+
outputs.push(block);
|
|
61
|
+
i = block.endLine + 1;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Match locals blocks: locals {
|
|
65
|
+
const localsMatch = line.match(/^locals\s*\{/);
|
|
66
|
+
if (localsMatch) {
|
|
67
|
+
const block = parseBlock(lines, i, 'locals', []);
|
|
68
|
+
locals.push(block);
|
|
69
|
+
i = block.endLine + 1;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Match module blocks: module "vpc" {
|
|
73
|
+
const moduleMatch = line.match(/^module\s+"([^"]+)"\s*\{/);
|
|
74
|
+
if (moduleMatch) {
|
|
75
|
+
const block = parseBlock(lines, i, 'module', [moduleMatch[1]]);
|
|
76
|
+
modules.push(block);
|
|
77
|
+
i = block.endLine + 1;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
return { resources, dataBlocks, variables, outputs, locals, modules };
|
|
83
|
+
}
|
|
84
|
+
function parseBlock(lines, startLine, type, labels) {
|
|
85
|
+
const attributes = {};
|
|
86
|
+
const blocks = [];
|
|
87
|
+
let braceDepth = 0;
|
|
88
|
+
let currentLine = startLine;
|
|
89
|
+
// Start with opening brace
|
|
90
|
+
braceDepth = 1;
|
|
91
|
+
currentLine++;
|
|
92
|
+
while (currentLine < lines.length && braceDepth > 0) {
|
|
93
|
+
const line = lines[currentLine].trim();
|
|
94
|
+
// Count braces
|
|
95
|
+
const openBraces = (line.match(/\{/g) || []).length;
|
|
96
|
+
const closeBraces = (line.match(/\}/g) || []).length;
|
|
97
|
+
braceDepth += openBraces - closeBraces;
|
|
98
|
+
if (braceDepth === 0)
|
|
99
|
+
break;
|
|
100
|
+
// Skip comments and empty lines
|
|
101
|
+
if (line.startsWith('#') || line.startsWith('//') || line === '') {
|
|
102
|
+
currentLine++;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Parse nested blocks (e.g., versioning { enabled = true })
|
|
106
|
+
const nestedBlockMatch = line.match(/^(\w+)\s*\{/);
|
|
107
|
+
if (nestedBlockMatch && !line.includes('=')) {
|
|
108
|
+
const nestedBlock = parseBlock(lines, currentLine, nestedBlockMatch[1], []);
|
|
109
|
+
blocks.push(nestedBlock);
|
|
110
|
+
// Attributes from nested blocks are also stored flat for easier access
|
|
111
|
+
attributes[nestedBlockMatch[1]] = nestedBlock.attributes;
|
|
112
|
+
currentLine = nestedBlock.endLine + 1;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Parse attributes (key = value)
|
|
116
|
+
const attrMatch = line.match(/^(\w+)\s*=\s*(.+?)(?:\s*#.*)?$/);
|
|
117
|
+
if (attrMatch) {
|
|
118
|
+
const key = attrMatch[1];
|
|
119
|
+
let valueStr = attrMatch[2].trim();
|
|
120
|
+
// Check if this is a multiline value (jsonencode, lists, objects)
|
|
121
|
+
const isMultiline = (valueStr.includes('jsonencode(') && !valueStr.includes(')')) ||
|
|
122
|
+
(valueStr.startsWith('[') && !valueStr.endsWith(']')) ||
|
|
123
|
+
(valueStr.startsWith('{') && !valueStr.endsWith('}'));
|
|
124
|
+
if (isMultiline) {
|
|
125
|
+
// Accumulate lines until we find the closing delimiter
|
|
126
|
+
let parenDepth = (valueStr.match(/\(/g) || []).length - (valueStr.match(/\)/g) || []).length;
|
|
127
|
+
let braceDepth = (valueStr.match(/\{/g) || []).length - (valueStr.match(/\}/g) || []).length;
|
|
128
|
+
let bracketDepth = (valueStr.match(/\[/g) || []).length - (valueStr.match(/\]/g) || []).length;
|
|
129
|
+
currentLine++;
|
|
130
|
+
while (currentLine < lines.length && (parenDepth > 0 || braceDepth > 0 || bracketDepth > 0)) {
|
|
131
|
+
const nextLine = lines[currentLine].trim();
|
|
132
|
+
// Skip empty lines and comments
|
|
133
|
+
if (nextLine === '' || nextLine.startsWith('#') || nextLine.startsWith('//')) {
|
|
134
|
+
currentLine++;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
valueStr += ' ' + nextLine; // Add space separator between lines
|
|
138
|
+
// Update depths
|
|
139
|
+
parenDepth += (nextLine.match(/\(/g) || []).length - (nextLine.match(/\)/g) || []).length;
|
|
140
|
+
braceDepth += (nextLine.match(/\{/g) || []).length - (nextLine.match(/\}/g) || []).length;
|
|
141
|
+
bracketDepth += (nextLine.match(/\[/g) || []).length - (nextLine.match(/\]/g) || []).length;
|
|
142
|
+
currentLine++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const value = parseValue(valueStr);
|
|
146
|
+
attributes[key] = value;
|
|
147
|
+
}
|
|
148
|
+
currentLine++;
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
type,
|
|
152
|
+
labels,
|
|
153
|
+
attributes,
|
|
154
|
+
blocks,
|
|
155
|
+
startLine: startLine + 1, // 1-indexed for display
|
|
156
|
+
endLine: currentLine + 1,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function parseValue(value) {
|
|
160
|
+
// Remove trailing comma
|
|
161
|
+
value = value.replace(/,$/, '').trim();
|
|
162
|
+
// Boolean
|
|
163
|
+
if (value === 'true')
|
|
164
|
+
return true;
|
|
165
|
+
if (value === 'false')
|
|
166
|
+
return false;
|
|
167
|
+
// Number
|
|
168
|
+
if (/^\d+(\.\d+)?$/.test(value))
|
|
169
|
+
return parseFloat(value);
|
|
170
|
+
// String (remove quotes)
|
|
171
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
172
|
+
return value.slice(1, -1);
|
|
173
|
+
}
|
|
174
|
+
// Handle jsonencode() function - extract JSON and parse it
|
|
175
|
+
const jsonencodeMatch = value.match(/jsonencode\s*\(([\s\S]+)\)$/);
|
|
176
|
+
if (jsonencodeMatch) {
|
|
177
|
+
try {
|
|
178
|
+
// Extract the content inside jsonencode()
|
|
179
|
+
let jsonContent = jsonencodeMatch[1].trim();
|
|
180
|
+
// Handle HCL-style JSON (without quotes on keys)
|
|
181
|
+
// Convert { Version = "2012-10-17" } to { "Version": "2012-10-17" }
|
|
182
|
+
// Step 1: Replace '=' with ':'
|
|
183
|
+
jsonContent = jsonContent.replace(/(\w+)\s*=/g, '"$1":');
|
|
184
|
+
// Step 2: Add commas after values (before next key or closing bracket/brace)
|
|
185
|
+
// Match: value followed by whitespace and then a key or closing delimiter
|
|
186
|
+
jsonContent = jsonContent
|
|
187
|
+
.replace(/("\w+":\s*"[^"]*")\s+(?=")/g, '$1,') // After quoted strings
|
|
188
|
+
.replace(/("\w+":\s*\d+)\s+(?=")/g, '$1,') // After numbers
|
|
189
|
+
.replace(/("\w+":\s*(?:true|false))\s+(?=")/g, '$1,') // After booleans
|
|
190
|
+
.replace(/(\])\s+(?=")/g, '$1,') // After arrays
|
|
191
|
+
.replace(/(\})\s+(?=")/g, '$1,'); // After objects
|
|
192
|
+
// Step 3: Quote unquoted string values
|
|
193
|
+
jsonContent = jsonContent.replace(/:\s*([a-zA-Z_]\w*(?:\s*\|\s*[a-zA-Z_]\w*)*)\s*([,\]\}])/g, ': "$1"$2');
|
|
194
|
+
return JSON.parse(jsonContent);
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
// If JSON parsing fails, return as string
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// List (basic support)
|
|
202
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
203
|
+
const items = value
|
|
204
|
+
.slice(1, -1)
|
|
205
|
+
.split(',')
|
|
206
|
+
.map(item => parseValue(item.trim()))
|
|
207
|
+
.filter(item => item !== '');
|
|
208
|
+
return items;
|
|
209
|
+
}
|
|
210
|
+
// Keep as string (references, complex expressions)
|
|
211
|
+
return value;
|
|
212
|
+
}
|
|
213
|
+
function detectProvider(resourceType) {
|
|
214
|
+
if (resourceType.startsWith('aws_'))
|
|
215
|
+
return 'aws';
|
|
216
|
+
if (resourceType.startsWith('azurerm_'))
|
|
217
|
+
return 'azure';
|
|
218
|
+
if (resourceType.startsWith('google_'))
|
|
219
|
+
return 'gcp';
|
|
220
|
+
return 'unknown';
|
|
221
|
+
}
|
|
222
|
+
// Helper to safely access nested attributes
|
|
223
|
+
function getAttribute(resource, path) {
|
|
224
|
+
const parts = path.split('.');
|
|
225
|
+
let current = resource.attributes;
|
|
226
|
+
for (const part of parts) {
|
|
227
|
+
if (current === undefined || current === null)
|
|
228
|
+
return undefined;
|
|
229
|
+
current = current[part];
|
|
230
|
+
}
|
|
231
|
+
return current;
|
|
232
|
+
}
|
|
233
|
+
// Helper to check if attribute exists
|
|
234
|
+
function hasAttribute(resource, path) {
|
|
235
|
+
return getAttribute(resource, path) !== undefined;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/terraform/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terraform Analyzer - Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* WR3: IaC Scanning - Terraform Support
|
|
5
|
+
* Defines TypeScript interfaces for Terraform HCL resources
|
|
6
|
+
*/
|
|
7
|
+
export interface TerraformBlock {
|
|
8
|
+
type: string;
|
|
9
|
+
labels: string[];
|
|
10
|
+
attributes: Record<string, any>;
|
|
11
|
+
blocks: TerraformBlock[];
|
|
12
|
+
startLine: number;
|
|
13
|
+
endLine: number;
|
|
14
|
+
}
|
|
15
|
+
export interface TerraformResource extends TerraformBlock {
|
|
16
|
+
resourceType: string;
|
|
17
|
+
resourceName: string;
|
|
18
|
+
provider: 'aws' | 'azure' | 'gcp' | 'unknown';
|
|
19
|
+
}
|
|
20
|
+
export interface ParsedTerraform {
|
|
21
|
+
resources: TerraformResource[];
|
|
22
|
+
dataBlocks: TerraformBlock[];
|
|
23
|
+
variables: TerraformBlock[];
|
|
24
|
+
outputs: TerraformBlock[];
|
|
25
|
+
locals: TerraformBlock[];
|
|
26
|
+
modules: TerraformBlock[];
|
|
27
|
+
}
|
|
28
|
+
export interface AWSS3Bucket {
|
|
29
|
+
bucket?: string;
|
|
30
|
+
acl?: string;
|
|
31
|
+
versioning?: {
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
};
|
|
34
|
+
logging?: {
|
|
35
|
+
target_bucket?: string;
|
|
36
|
+
};
|
|
37
|
+
server_side_encryption_configuration?: {
|
|
38
|
+
rule?: {
|
|
39
|
+
apply_server_side_encryption_by_default?: {
|
|
40
|
+
sse_algorithm?: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
public_access_block?: {
|
|
45
|
+
block_public_acls?: boolean;
|
|
46
|
+
block_public_policy?: boolean;
|
|
47
|
+
ignore_public_acls?: boolean;
|
|
48
|
+
restrict_public_buckets?: boolean;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export interface AWSIAMPolicy {
|
|
52
|
+
name?: string;
|
|
53
|
+
policy?: string | object;
|
|
54
|
+
path?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface AWSIAMRole {
|
|
57
|
+
name?: string;
|
|
58
|
+
assume_role_policy?: string | object;
|
|
59
|
+
managed_policy_arns?: string[];
|
|
60
|
+
}
|
|
61
|
+
export interface AWSIAMPolicyDocument {
|
|
62
|
+
Version?: string;
|
|
63
|
+
Statement?: Array<{
|
|
64
|
+
Effect?: 'Allow' | 'Deny';
|
|
65
|
+
Action?: string | string[];
|
|
66
|
+
Resource?: string | string[];
|
|
67
|
+
Principal?: any;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/terraform/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAGD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,oCAAoC,CAAC,EAAE;QACrC,IAAI,CAAC,EAAE;YACL,uCAAuC,CAAC,EAAE;gBACxC,aAAa,CAAC,EAAE,MAAM,CAAC;aACxB,CAAC;SACH,CAAC;KACH,CAAC;IACF,mBAAmB,CAAC,EAAE;QACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,uBAAuB,CAAC,EAAE,OAAO,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC7B,SAAS,CAAC,EAAE,GAAG,CAAC;KACjB,CAAC,CAAC;CACJ"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Terraform Analyzer - Type Definitions
|
|
4
|
+
*
|
|
5
|
+
* WR3: IaC Scanning - Terraform Support
|
|
6
|
+
* Defines TypeScript interfaces for Terraform HCL resources
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/terraform/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⚠️ SHARED MODULE: Terraform Security Analyzer
|
|
3
|
+
*
|
|
4
|
+
* CRITICAL: This module is used by BOTH WebTool and GitHub App
|
|
5
|
+
*
|
|
6
|
+
* WebTool uses this for:
|
|
7
|
+
* - /api/analyze endpoint - Interactive single-file IaC analysis (<5s target)
|
|
8
|
+
* - Real-time misconfiguration detection for individual developers
|
|
9
|
+
*
|
|
10
|
+
* GitHub App uses this for:
|
|
11
|
+
* - /api/github/webhook - Batch PR analysis of Terraform files (10-30s OK)
|
|
12
|
+
* - Automated IaC security checks for professional teams
|
|
13
|
+
*
|
|
14
|
+
* WR3: IaC Scanning - Terraform Support
|
|
15
|
+
* Day 1-2: AWS S3 and IAM checks (10 checks total)
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ BEFORE MODIFYING THIS FILE:
|
|
18
|
+
* 1. Run all analyzer tests: npm test terraform-analyzer
|
|
19
|
+
* 2. Test WebTool: Paste Terraform at /analyze → Verify results
|
|
20
|
+
* 3. Test GitHub: Open PR with .tf file → Verify webhook comment
|
|
21
|
+
* 4. Verify performance: Analysis must complete in <5s per file
|
|
22
|
+
* 5. Check detection rate: All 10 Terraform checks must still detect
|
|
23
|
+
*
|
|
24
|
+
* CRITICAL OUTPUT FORMAT (DO NOT CHANGE):
|
|
25
|
+
* - result.security.vulnerabilities - Used by both systems
|
|
26
|
+
* - Each vulnerability has: line, message, severity, cvssScore, owasp, cwe
|
|
27
|
+
* - Changing this structure breaks BOTH WebTool and GitHub UI parsing
|
|
28
|
+
*
|
|
29
|
+
* See: docs/technical/WEBTOOL_GITHUB_SEPARATION.md
|
|
30
|
+
*
|
|
31
|
+
* Last modified: 2026-02-04 (WR3 Day 1-2)
|
|
32
|
+
* Last verified (both systems): TBD (after first commit)
|
|
33
|
+
*/
|
|
34
|
+
import { ICodeAnalyzer, AnalyzerInput, AnalyzerResult } from './types';
|
|
35
|
+
import { SupportedLanguage } from '../types';
|
|
36
|
+
export declare class TerraformAnalyzer implements ICodeAnalyzer {
|
|
37
|
+
readonly language: SupportedLanguage;
|
|
38
|
+
analyze(input: AnalyzerInput): Promise<AnalyzerResult>;
|
|
39
|
+
private analyzeSecurity;
|
|
40
|
+
private calculateMetrics;
|
|
41
|
+
private detectProductionContext;
|
|
42
|
+
validateSyntax(code: string): Promise<boolean>;
|
|
43
|
+
getLanguageInfo(): {
|
|
44
|
+
name: string;
|
|
45
|
+
extensions: string[];
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=terraform-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-analyzer.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/analyzers/terraform-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAyB,MAAM,SAAS,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAgB7C,qBAAa,iBAAkB,YAAW,aAAa;IACrD,SAAgB,QAAQ,EAAE,iBAAiB,CAAe;IAEpD,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA6C5D,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,uBAAuB;IAMzB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASpD,eAAe,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB;CAOF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ⚠️ SHARED MODULE: Terraform Security Analyzer
|
|
4
|
+
*
|
|
5
|
+
* CRITICAL: This module is used by BOTH WebTool and GitHub App
|
|
6
|
+
*
|
|
7
|
+
* WebTool uses this for:
|
|
8
|
+
* - /api/analyze endpoint - Interactive single-file IaC analysis (<5s target)
|
|
9
|
+
* - Real-time misconfiguration detection for individual developers
|
|
10
|
+
*
|
|
11
|
+
* GitHub App uses this for:
|
|
12
|
+
* - /api/github/webhook - Batch PR analysis of Terraform files (10-30s OK)
|
|
13
|
+
* - Automated IaC security checks for professional teams
|
|
14
|
+
*
|
|
15
|
+
* WR3: IaC Scanning - Terraform Support
|
|
16
|
+
* Day 1-2: AWS S3 and IAM checks (10 checks total)
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ BEFORE MODIFYING THIS FILE:
|
|
19
|
+
* 1. Run all analyzer tests: npm test terraform-analyzer
|
|
20
|
+
* 2. Test WebTool: Paste Terraform at /analyze → Verify results
|
|
21
|
+
* 3. Test GitHub: Open PR with .tf file → Verify webhook comment
|
|
22
|
+
* 4. Verify performance: Analysis must complete in <5s per file
|
|
23
|
+
* 5. Check detection rate: All 10 Terraform checks must still detect
|
|
24
|
+
*
|
|
25
|
+
* CRITICAL OUTPUT FORMAT (DO NOT CHANGE):
|
|
26
|
+
* - result.security.vulnerabilities - Used by both systems
|
|
27
|
+
* - Each vulnerability has: line, message, severity, cvssScore, owasp, cwe
|
|
28
|
+
* - Changing this structure breaks BOTH WebTool and GitHub UI parsing
|
|
29
|
+
*
|
|
30
|
+
* See: docs/technical/WEBTOOL_GITHUB_SEPARATION.md
|
|
31
|
+
*
|
|
32
|
+
* Last modified: 2026-02-04 (WR3 Day 1-2)
|
|
33
|
+
* Last verified (both systems): TBD (after first commit)
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TerraformAnalyzer = void 0;
|
|
37
|
+
const parser_1 = require("./terraform/parser");
|
|
38
|
+
const aws_checks_1 = require("./terraform/aws-checks");
|
|
39
|
+
class TerraformAnalyzer {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.language = 'terraform';
|
|
42
|
+
}
|
|
43
|
+
async analyze(input) {
|
|
44
|
+
const result = {
|
|
45
|
+
syntax: { valid: true, errors: [], lineErrors: [] },
|
|
46
|
+
quality: { score: 100, issues: [] },
|
|
47
|
+
performance: { score: 100, suggestions: [] },
|
|
48
|
+
security: { vulnerabilities: [] },
|
|
49
|
+
metrics: { complexity: 1, maintainability: 100, lines: 0, functions: 0 },
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
// Parse Terraform HCL
|
|
53
|
+
const parsed = (0, parser_1.parseTerraform)(input.code);
|
|
54
|
+
// Analyze security for all resources
|
|
55
|
+
this.analyzeSecurity(parsed.resources, result);
|
|
56
|
+
// Calculate basic metrics
|
|
57
|
+
this.calculateMetrics(input.code, result);
|
|
58
|
+
// Feature 1 Phase 1: Smart Triage with EPSS scoring
|
|
59
|
+
// TODO (WR3 Week 2): Re-enable triage after fixing severity vs priority field issue
|
|
60
|
+
// For MVP Day 1-2, disabled to test base checks without triage interference
|
|
61
|
+
// try {
|
|
62
|
+
// if (result.security.vulnerabilities.length > 0) {
|
|
63
|
+
// const triageResults = await triageSecurityIssues(result.security.vulnerabilities, {
|
|
64
|
+
// environmentContext: {
|
|
65
|
+
// isProduction: this.detectProductionContext(input.filename || ''),
|
|
66
|
+
// },
|
|
67
|
+
// });
|
|
68
|
+
// // Update vulnerabilities with triaged versions (priority, triageReason, epssScore)
|
|
69
|
+
// result.security.vulnerabilities = triageResults.map(tr => tr.issue);
|
|
70
|
+
// }
|
|
71
|
+
// } catch (triageError) {
|
|
72
|
+
// // Triage is optional enhancement - don't fail analysis if it errors
|
|
73
|
+
// console.warn('[Terraform Analyzer] Triage service failed:', triageError instanceof Error ? triageError.message : 'Unknown error');
|
|
74
|
+
// }
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
78
|
+
result.syntax.valid = false;
|
|
79
|
+
result.syntax.errors.push(`Terraform analysis error: ${errorMessage}`);
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
analyzeSecurity(resources, result) {
|
|
84
|
+
const checks = [
|
|
85
|
+
// AWS S3 Checks (5 checks)
|
|
86
|
+
aws_checks_1.checkS3PublicACL,
|
|
87
|
+
aws_checks_1.checkS3Encryption,
|
|
88
|
+
aws_checks_1.checkS3Versioning,
|
|
89
|
+
aws_checks_1.checkS3Logging,
|
|
90
|
+
aws_checks_1.checkS3PublicAccessBlock,
|
|
91
|
+
// AWS IAM Checks (5 checks)
|
|
92
|
+
aws_checks_1.checkIAMWildcardActions,
|
|
93
|
+
aws_checks_1.checkIAMWildcardResources,
|
|
94
|
+
aws_checks_1.checkIAMAdminPolicy,
|
|
95
|
+
aws_checks_1.checkIAMPrivilegeEscalation,
|
|
96
|
+
aws_checks_1.checkIAMAssumeRolePolicy,
|
|
97
|
+
];
|
|
98
|
+
for (const resource of resources) {
|
|
99
|
+
for (const check of checks) {
|
|
100
|
+
const vulnerability = check(resource);
|
|
101
|
+
if (vulnerability) {
|
|
102
|
+
result.security.vulnerabilities.push(vulnerability);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
calculateMetrics(code, result) {
|
|
108
|
+
const lines = code.split('\n');
|
|
109
|
+
result.metrics.lines = lines.length;
|
|
110
|
+
// Count resources as "functions" for metrics
|
|
111
|
+
const resourceCount = (code.match(/^resource\s+"/gm) || []).length;
|
|
112
|
+
result.metrics.functions = resourceCount;
|
|
113
|
+
// Basic complexity based on number of resources
|
|
114
|
+
result.metrics.complexity = Math.max(1, resourceCount);
|
|
115
|
+
result.metrics.maintainability = Math.max(50, 100 - resourceCount * 2);
|
|
116
|
+
}
|
|
117
|
+
detectProductionContext(filename) {
|
|
118
|
+
const prodIndicators = ['prod', 'production', 'live', 'main'];
|
|
119
|
+
const filenameLower = filename.toLowerCase();
|
|
120
|
+
return prodIndicators.some(indicator => filenameLower.includes(indicator));
|
|
121
|
+
}
|
|
122
|
+
async validateSyntax(code) {
|
|
123
|
+
try {
|
|
124
|
+
(0, parser_1.parseTerraform)(code);
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
getLanguageInfo() {
|
|
132
|
+
return {
|
|
133
|
+
name: 'Terraform',
|
|
134
|
+
extensions: ['.tf', '.tfvars'],
|
|
135
|
+
description: 'Infrastructure as Code (IaC) security scanning for Terraform HCL files',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.TerraformAnalyzer = TerraformAnalyzer;
|
|
140
|
+
//# sourceMappingURL=terraform-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terraform-analyzer.js","sourceRoot":"","sources":["../../../../../../src/lib/analyzers/terraform-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-security.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/typescript/security-checks/type-security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,GACd,qBAAqB,EAAE,
|
|
1
|
+
{"version":3,"file":"type-security.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/typescript/security-checks/type-security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,GACd,qBAAqB,EAAE,CA0FzB"}
|
|
@@ -35,14 +35,29 @@ function checkTypeSecurity(lines) {
|
|
|
35
35
|
// Skip comments and empty lines
|
|
36
36
|
if (!trimmed || inMultiLineComment || trimmed.startsWith('//') || trimmed.startsWith('*'))
|
|
37
37
|
return;
|
|
38
|
-
// TypeScript-specific:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'
|
|
45
|
-
|
|
38
|
+
// TypeScript-specific: 19a. Generic 'as any' - LOW (code quality, OWASP 2021/2025)
|
|
39
|
+
// Dec 16, 2025: Reclassified to LOW - code quality issue, not direct security vulnerability
|
|
40
|
+
// Uses 'any-type-usage' category which maps to LOW severity (CVSS 0.0) in centralized scoring
|
|
41
|
+
if (trimmed.includes('as any')) {
|
|
42
|
+
const isSecuritySensitive = trimmed.includes('eval') || trimmed.includes('innerHTML');
|
|
43
|
+
if (isSecuritySensitive) {
|
|
44
|
+
// 19b. 'as any' in security-sensitive contexts - HIGH
|
|
45
|
+
vulnerabilities.push((0, createVulnerability_1.createTypeScriptSecurityVulnerability)('type-assertion-security', 'Type assertion "as any" in sensitive context', 'Use specific types to maintain security', lineNumber, 'Using "as any" bypasses TypeScript\'s type checking, potentially allowing unsafe values to reach security-critical operations like eval() or innerHTML.', '(userInput as any).eval(); // Bypasses type safety, allows arbitrary code execution', [
|
|
46
|
+
'Type safety bypass',
|
|
47
|
+
'Runtime security vulnerabilities',
|
|
48
|
+
'Code injection risks',
|
|
49
|
+
'XSS vulnerabilities'
|
|
50
|
+
], 'const unsafeCode = userInput as any;\neval(unsafeCode); // DANGEROUS: no type validation', 'const validatedCode: string = validateCode(userInput);\n// Don\'t use eval() at all, but if necessary, ensure proper validation', 'Avoid "as any" in security-sensitive contexts. Use proper type guards and validation instead of type assertions'));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Generic 'as any' - code quality issue
|
|
54
|
+
vulnerabilities.push((0, createVulnerability_1.createTypeScriptSecurityVulnerability)('any-type-usage', 'Type assertion "as any" bypasses type safety', 'Use specific types or type guards instead of "as any"', lineNumber, 'Using "as any" disables TypeScript\'s type checking, which can mask bugs and make code harder to maintain. While not directly exploitable, it reduces code quality and may hide underlying issues.', 'const data = userInput as any; // Bypasses all type checks', [
|
|
55
|
+
'Reduces code maintainability',
|
|
56
|
+
'Can mask underlying bugs',
|
|
57
|
+
'Makes refactoring harder',
|
|
58
|
+
'Decreases type safety benefits'
|
|
59
|
+
], 'const data = userInput as any;\ndata.someMethod(); // No type checking, runtime errors possible', '// Use type guards or proper typing\nif (isValidData(userInput)) {\n const data: DataType = userInput;\n data.someMethod(); // Type-safe\n}', 'Avoid "as any". Use proper type guards (typeof, instanceof), type predicates, or refactor code to use correct types. TypeScript\'s type system is designed to catch errors at compile time.'));
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
62
|
// TypeScript-specific: 20. Non-null assertions in security contexts - MEDIUM
|
|
48
63
|
if (trimmed.includes('!') && trimmed.match(/password|token|secret|auth/i)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-security.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/typescript/security-checks/type-security.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAeH,
|
|
1
|
+
{"version":3,"file":"type-security.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/typescript/security-checks/type-security.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAeH,8CA4FC;AAxGD,sEAAqF;AAErF;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAC/B,KAAe;IAEf,MAAM,eAAe,GAA4B,EAAE,CAAC;IACpD,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,8CAA8C;QAC9C,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,kBAAkB,GAAG,KAAK,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,OAAO,IAAI,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;QAElG,mFAAmF;QACnF,4FAA4F;QAC5F,8FAA8F;QAC9F,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAEtF,IAAI,mBAAmB,EAAE,CAAC;gBACxB,sDAAsD;gBACtD,eAAe,CAAC,IAAI,CAAC,IAAA,2DAAqC,EACxD,yBAAyB,EACzB,8CAA8C,EAC9C,yCAAyC,EACzC,UAAU,EACV,yJAAyJ,EACzJ,qFAAqF,EACrF;oBACE,oBAAoB;oBACpB,kCAAkC;oBAClC,sBAAsB;oBACtB,qBAAqB;iBACtB,EACD,0FAA0F,EAC1F,iIAAiI,EACjI,iHAAiH,CAClH,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,eAAe,CAAC,IAAI,CAAC,IAAA,2DAAqC,EACxD,gBAAgB,EAChB,8CAA8C,EAC9C,uDAAuD,EACvD,UAAU,EACV,oMAAoM,EACpM,4DAA4D,EAC5D;oBACE,8BAA8B;oBAC9B,0BAA0B;oBAC1B,0BAA0B;oBAC1B,gCAAgC;iBACjC,EACD,iGAAiG,EACjG,+IAA+I,EAC/I,6LAA6L,CAC9L,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,6EAA6E;QAC7E,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,EAAE,CAAC;YAC1E,eAAe,CAAC,IAAI,CAAC,IAAA,2DAAqC,EACxD,6BAA6B,EAC7B,yCAAyC,EACzC,qCAAqC,EACrC,UAAU,EACV,yIAAyI,EACzI,8GAA8G,EAC9G;gBACE,uBAAuB;gBACvB,wBAAwB;gBACxB,2CAA2C;gBAC3C,uBAAuB;aACxB,EACD,yEAAyE,EACzE,4GAA4G,EAC5G,mIAAmI,CACpI,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epss-service.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/security/epss-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoBH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AAeD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"epss-service.d.ts","sourceRoot":"","sources":["../../../../../../src/lib/security/epss-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAoBH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AAeD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA0I1E;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAG3E;AAgCD;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAahF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IACrD,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB,CAsBA;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EAAE,EAChB,SAAS,GAAE,MAAW,GACrB,OAAO,CAAC,SAAS,EAAE,CAAC,CAatB"}
|