visus-mcp 0.6.2 → 0.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/.claude/settings.local.json +15 -1
- package/.env.status +7 -0
- package/CHANGELOG.md +110 -0
- package/CLAUDE.md +3 -0
- package/README.md +29 -19
- package/SECURITY.md +2 -0
- package/STATUS.md +320 -12
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +27 -5
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/content-handlers/index.d.ts +36 -0
- package/dist/content-handlers/index.d.ts.map +1 -0
- package/dist/content-handlers/index.js +59 -0
- package/dist/content-handlers/index.js.map +1 -0
- package/dist/content-handlers/json-handler.d.ts +28 -0
- package/dist/content-handlers/json-handler.d.ts.map +1 -0
- package/dist/content-handlers/json-handler.js +116 -0
- package/dist/content-handlers/json-handler.js.map +1 -0
- package/dist/content-handlers/pdf-handler.d.ts +29 -0
- package/dist/content-handlers/pdf-handler.d.ts.map +1 -0
- package/dist/content-handlers/pdf-handler.js +77 -0
- package/dist/content-handlers/pdf-handler.js.map +1 -0
- package/dist/content-handlers/svg-handler.d.ts +35 -0
- package/dist/content-handlers/svg-handler.d.ts.map +1 -0
- package/dist/content-handlers/svg-handler.js +206 -0
- package/dist/content-handlers/svg-handler.js.map +1 -0
- package/dist/content-handlers/types.d.ts +42 -0
- package/dist/content-handlers/types.d.ts.map +1 -0
- package/dist/content-handlers/types.js +7 -0
- package/dist/content-handlers/types.js.map +1 -0
- package/dist/sanitizer/framework-mapper.d.ts +4 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -1
- package/dist/sanitizer/framework-mapper.js +92 -0
- package/dist/sanitizer/framework-mapper.js.map +1 -1
- package/dist/sanitizer/threat-reporter.d.ts +5 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -1
- package/dist/sanitizer/threat-reporter.js +15 -6
- package/dist/sanitizer/threat-reporter.js.map +1 -1
- package/dist/tools/fetch-structured.d.ts.map +1 -1
- package/dist/tools/fetch-structured.js +4 -0
- package/dist/tools/fetch-structured.js.map +1 -1
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +68 -4
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +4 -0
- package/dist/tools/read.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -1
- package/server.json +25 -14
- package/src/browser/playwright-renderer.ts +29 -6
- package/src/content-handlers/index.ts +72 -0
- package/src/content-handlers/json-handler.ts +137 -0
- package/src/content-handlers/pdf-handler.ts +91 -0
- package/src/content-handlers/svg-handler.ts +243 -0
- package/src/content-handlers/types.ts +44 -0
- package/src/sanitizer/framework-mapper.ts +94 -0
- package/src/sanitizer/threat-reporter.ts +17 -6
- package/src/tools/fetch-structured.ts +5 -0
- package/src/tools/fetch.ts +76 -4
- package/src/tools/read.ts +5 -0
- package/src/types.ts +9 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
- package/.github/ISSUE_TEMPLATE/false_positive.md +0 -43
- package/.github/ISSUE_TEMPLATE/new_pattern.md +0 -49
- package/.github/ISSUE_TEMPLATE/security_report.md +0 -31
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -39
- package/.mcpregistry_github_token +0 -1
- package/.mcpregistry_registry_token +0 -1
- package/CONTRIBUTING.md +0 -329
- package/LINKEDIN-STRATEGY.md +0 -367
- package/ROADMAP.md +0 -221
- package/SECURITY-AUDIT-v1.md +0 -277
- package/SUBMISSION.md +0 -66
- package/TROUBLESHOOT-AUTH-20260322-2019.md +0 -291
- package/TROUBLESHOOT-BUILD-20260319-1450.md +0 -546
- package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +0 -415
- package/TROUBLESHOOT-COGNITO-JWT-20260324.md +0 -592
- package/TROUBLESHOOT-FETCH-20260320-1150.md +0 -168
- package/TROUBLESHOOT-JEST-20260323-1357.md +0 -139
- package/TROUBLESHOOT-LAMBDA-20260322-1945.md +0 -183
- package/TROUBLESHOOT-PLAYWRIGHT-20260321-1549.md +0 -217
- package/TROUBLESHOOT-SSL-20260320-1138.md +0 -171
- package/TROUBLESHOOT-STRUCTURED-20260320-1200.md +0 -246
- package/TROUBLESHOOT-TEST-20260320-0942.md +0 -281
- package/VISUS-CLAUDE-CODE-PROMPT.md +0 -324
- package/VISUS-PROJECT-PLAN.md +0 -205
- package/cdk.json +0 -73
- package/infrastructure/app.ts +0 -39
- package/infrastructure/stack.ts +0 -298
- package/jest.config.js +0 -33
- package/jest.setup.js +0 -9
- package/lambda-deploy/index.js +0 -81512
- package/lambda-deploy/index.js.map +0 -7
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +0 -25
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +0 -1
- package/lambda-package/browser/__mocks__/playwright-renderer.js +0 -119
- package/lambda-package/browser/__mocks__/playwright-renderer.js.map +0 -1
- package/lambda-package/browser/playwright-renderer.d.ts +0 -40
- package/lambda-package/browser/playwright-renderer.d.ts.map +0 -1
- package/lambda-package/browser/playwright-renderer.js +0 -214
- package/lambda-package/browser/playwright-renderer.js.map +0 -1
- package/lambda-package/browser/reader.d.ts +0 -31
- package/lambda-package/browser/reader.d.ts.map +0 -1
- package/lambda-package/browser/reader.js +0 -98
- package/lambda-package/browser/reader.js.map +0 -1
- package/lambda-package/index.d.ts +0 -18
- package/lambda-package/index.d.ts.map +0 -1
- package/lambda-package/index.js +0 -238
- package/lambda-package/index.js.map +0 -1
- package/lambda-package/lambda-handler.d.ts +0 -28
- package/lambda-package/lambda-handler.d.ts.map +0 -1
- package/lambda-package/lambda-handler.js +0 -257
- package/lambda-package/lambda-handler.js.map +0 -1
- package/lambda-package/package-lock.json +0 -7435
- package/lambda-package/package.json +0 -74
- package/lambda-package/runtime.d.ts +0 -50
- package/lambda-package/runtime.d.ts.map +0 -1
- package/lambda-package/runtime.js +0 -86
- package/lambda-package/runtime.js.map +0 -1
- package/lambda-package/sanitizer/elicit-runner.d.ts +0 -48
- package/lambda-package/sanitizer/elicit-runner.d.ts.map +0 -1
- package/lambda-package/sanitizer/elicit-runner.js +0 -100
- package/lambda-package/sanitizer/elicit-runner.js.map +0 -1
- package/lambda-package/sanitizer/framework-mapper.d.ts +0 -24
- package/lambda-package/sanitizer/framework-mapper.d.ts.map +0 -1
- package/lambda-package/sanitizer/framework-mapper.js +0 -342
- package/lambda-package/sanitizer/framework-mapper.js.map +0 -1
- package/lambda-package/sanitizer/hitl-gate.d.ts +0 -69
- package/lambda-package/sanitizer/hitl-gate.d.ts.map +0 -1
- package/lambda-package/sanitizer/hitl-gate.js +0 -101
- package/lambda-package/sanitizer/hitl-gate.js.map +0 -1
- package/lambda-package/sanitizer/index.d.ts +0 -63
- package/lambda-package/sanitizer/index.d.ts.map +0 -1
- package/lambda-package/sanitizer/index.js +0 -105
- package/lambda-package/sanitizer/index.js.map +0 -1
- package/lambda-package/sanitizer/injection-detector.d.ts +0 -34
- package/lambda-package/sanitizer/injection-detector.d.ts.map +0 -1
- package/lambda-package/sanitizer/injection-detector.js +0 -89
- package/lambda-package/sanitizer/injection-detector.js.map +0 -1
- package/lambda-package/sanitizer/patterns.d.ts +0 -30
- package/lambda-package/sanitizer/patterns.d.ts.map +0 -1
- package/lambda-package/sanitizer/patterns.js +0 -372
- package/lambda-package/sanitizer/patterns.js.map +0 -1
- package/lambda-package/sanitizer/pii-allowlist.d.ts +0 -49
- package/lambda-package/sanitizer/pii-allowlist.d.ts.map +0 -1
- package/lambda-package/sanitizer/pii-allowlist.js +0 -231
- package/lambda-package/sanitizer/pii-allowlist.js.map +0 -1
- package/lambda-package/sanitizer/pii-redactor.d.ts +0 -41
- package/lambda-package/sanitizer/pii-redactor.d.ts.map +0 -1
- package/lambda-package/sanitizer/pii-redactor.js +0 -213
- package/lambda-package/sanitizer/pii-redactor.js.map +0 -1
- package/lambda-package/sanitizer/severity-classifier.d.ts +0 -33
- package/lambda-package/sanitizer/severity-classifier.d.ts.map +0 -1
- package/lambda-package/sanitizer/severity-classifier.js +0 -113
- package/lambda-package/sanitizer/severity-classifier.js.map +0 -1
- package/lambda-package/sanitizer/threat-reporter.d.ts +0 -66
- package/lambda-package/sanitizer/threat-reporter.d.ts.map +0 -1
- package/lambda-package/sanitizer/threat-reporter.js +0 -163
- package/lambda-package/sanitizer/threat-reporter.js.map +0 -1
- package/lambda-package/tools/fetch-structured.d.ts +0 -51
- package/lambda-package/tools/fetch-structured.d.ts.map +0 -1
- package/lambda-package/tools/fetch-structured.js +0 -237
- package/lambda-package/tools/fetch-structured.js.map +0 -1
- package/lambda-package/tools/fetch.d.ts +0 -49
- package/lambda-package/tools/fetch.d.ts.map +0 -1
- package/lambda-package/tools/fetch.js +0 -131
- package/lambda-package/tools/fetch.js.map +0 -1
- package/lambda-package/tools/read.d.ts +0 -51
- package/lambda-package/tools/read.d.ts.map +0 -1
- package/lambda-package/tools/read.js +0 -127
- package/lambda-package/tools/read.js.map +0 -1
- package/lambda-package/tools/search.d.ts +0 -45
- package/lambda-package/tools/search.d.ts.map +0 -1
- package/lambda-package/tools/search.js +0 -220
- package/lambda-package/tools/search.js.map +0 -1
- package/lambda-package/types.d.ts +0 -167
- package/lambda-package/types.d.ts.map +0 -1
- package/lambda-package/types.js +0 -16
- package/lambda-package/types.js.map +0 -1
- package/lambda-package/utils/format-converter.d.ts +0 -39
- package/lambda-package/utils/format-converter.d.ts.map +0 -1
- package/lambda-package/utils/format-converter.js +0 -191
- package/lambda-package/utils/format-converter.js.map +0 -1
- package/lambda-package/utils/truncate.d.ts +0 -26
- package/lambda-package/utils/truncate.d.ts.map +0 -1
- package/lambda-package/utils/truncate.js +0 -54
- package/lambda-package/utils/truncate.js.map +0 -1
- package/lambda.zip +0 -0
- package/test-output.txt +0 -4
- package/tests/auth-smoke.test.ts +0 -480
- package/tests/elicit-runner.test.ts +0 -232
- package/tests/fetch-tool.test.ts +0 -922
- package/tests/hitl-gate.test.ts +0 -267
- package/tests/injection-corpus.ts +0 -338
- package/tests/pii-allowlist.test.ts +0 -282
- package/tests/reader.test.ts +0 -353
- package/tests/sanitizer.test.ts +0 -358
- package/tests/search.test.ts +0 -456
- package/tests/threat-reporter.test.ts +0 -334
- package/tsconfig.cdk.json +0 -35
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Content Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles application/json content type. Recursively traverses all nodes in the JSON
|
|
5
|
+
* object tree and applies the full injection pattern registry to every string value.
|
|
6
|
+
*
|
|
7
|
+
* What it handles:
|
|
8
|
+
* - All string values in the JSON tree (any depth)
|
|
9
|
+
* - Arrays, nested objects, and mixed-type arrays
|
|
10
|
+
* - Falls back to plain text pipeline if JSON.parse fails
|
|
11
|
+
*
|
|
12
|
+
* What it strips:
|
|
13
|
+
* - Nothing (preserves original structure)
|
|
14
|
+
*
|
|
15
|
+
* What it passes through:
|
|
16
|
+
* - Sanitized JSON with original structure preserved
|
|
17
|
+
* - All non-string values pass through unchanged
|
|
18
|
+
*/
|
|
19
|
+
import { sanitize } from '../sanitizer/index.js';
|
|
20
|
+
/**
|
|
21
|
+
* Handle JSON content
|
|
22
|
+
*
|
|
23
|
+
* @param content - Raw JSON string
|
|
24
|
+
* @param mimeType - Original MIME type
|
|
25
|
+
* @returns Sanitized handler result
|
|
26
|
+
*/
|
|
27
|
+
export function handleJson(content, mimeType) {
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
// Convert Buffer to string if needed
|
|
30
|
+
const jsonString = Buffer.isBuffer(content) ? content.toString('utf-8') : content;
|
|
31
|
+
try {
|
|
32
|
+
// Parse JSON
|
|
33
|
+
const parsed = JSON.parse(jsonString);
|
|
34
|
+
// Track sanitization metadata across all fields
|
|
35
|
+
let sanitizedFieldCount = 0;
|
|
36
|
+
const allPatternsDetected = new Set();
|
|
37
|
+
const allPiiTypesRedacted = new Set();
|
|
38
|
+
const allPiiAllowlisted = [];
|
|
39
|
+
// Recursively sanitize all string values
|
|
40
|
+
const sanitized = recursiveSanitize(parsed, (text) => {
|
|
41
|
+
const result = sanitize(text);
|
|
42
|
+
if (result.sanitization.content_modified) {
|
|
43
|
+
sanitizedFieldCount++;
|
|
44
|
+
}
|
|
45
|
+
// Aggregate metadata
|
|
46
|
+
result.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
|
|
47
|
+
result.sanitization.pii_types_redacted.forEach(p => allPiiTypesRedacted.add(p));
|
|
48
|
+
allPiiAllowlisted.push(...result.sanitization.pii_allowlisted);
|
|
49
|
+
return result.content;
|
|
50
|
+
});
|
|
51
|
+
// Re-stringify with 2-space indent
|
|
52
|
+
const sanitizedJson = JSON.stringify(sanitized, null, 2);
|
|
53
|
+
const processingTime = Date.now() - startTime;
|
|
54
|
+
return {
|
|
55
|
+
status: 'sanitized',
|
|
56
|
+
content_type: mimeType,
|
|
57
|
+
sanitized_content: sanitizedJson,
|
|
58
|
+
sanitization: {
|
|
59
|
+
patterns_detected: Array.from(allPatternsDetected),
|
|
60
|
+
pii_types_redacted: Array.from(allPiiTypesRedacted),
|
|
61
|
+
pii_allowlisted: allPiiAllowlisted,
|
|
62
|
+
sanitized_fields: sanitizedFieldCount
|
|
63
|
+
},
|
|
64
|
+
processing_time_ms: processingTime
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// JSON.parse failed - fall back to plain text sanitization
|
|
69
|
+
const sanitizationResult = sanitize(jsonString);
|
|
70
|
+
const processingTime = Date.now() - startTime;
|
|
71
|
+
return {
|
|
72
|
+
status: 'sanitized',
|
|
73
|
+
content_type: mimeType,
|
|
74
|
+
sanitized_content: sanitizationResult.content,
|
|
75
|
+
sanitization: {
|
|
76
|
+
patterns_detected: sanitizationResult.sanitization.patterns_detected,
|
|
77
|
+
pii_types_redacted: sanitizationResult.sanitization.pii_types_redacted,
|
|
78
|
+
pii_allowlisted: sanitizationResult.sanitization.pii_allowlisted,
|
|
79
|
+
sanitized_fields: sanitizationResult.sanitization.patterns_detected.length
|
|
80
|
+
},
|
|
81
|
+
processing_time_ms: processingTime
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Recursively traverse JSON tree and sanitize all string values
|
|
87
|
+
*
|
|
88
|
+
* @param obj - JSON object/array/primitive
|
|
89
|
+
* @param sanitizeFn - Function to sanitize string values
|
|
90
|
+
* @returns Sanitized object with same structure
|
|
91
|
+
*/
|
|
92
|
+
function recursiveSanitize(obj, sanitizeFn) {
|
|
93
|
+
// Handle null
|
|
94
|
+
if (obj === null) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
// Handle string - sanitize it
|
|
98
|
+
if (typeof obj === 'string') {
|
|
99
|
+
return sanitizeFn(obj);
|
|
100
|
+
}
|
|
101
|
+
// Handle array - recursively sanitize each element
|
|
102
|
+
if (Array.isArray(obj)) {
|
|
103
|
+
return obj.map((item) => recursiveSanitize(item, sanitizeFn));
|
|
104
|
+
}
|
|
105
|
+
// Handle object - recursively sanitize each value
|
|
106
|
+
if (typeof obj === 'object') {
|
|
107
|
+
const sanitizedObj = {};
|
|
108
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
109
|
+
sanitizedObj[key] = recursiveSanitize(value, sanitizeFn);
|
|
110
|
+
}
|
|
111
|
+
return sanitizedObj;
|
|
112
|
+
}
|
|
113
|
+
// Handle primitives (number, boolean, undefined) - pass through
|
|
114
|
+
return obj;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=json-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-handler.js","sourceRoot":"","sources":["../../src/content-handlers/json-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,OAAwB,EACxB,QAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,qCAAqC;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAElF,IAAI,CAAC;QACH,aAAa;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAEtC,gDAAgD;QAChD,IAAI,mBAAmB,GAAG,CAAC,CAAC;QAC5B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9C,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9C,MAAM,iBAAiB,GAA2D,EAAE,CAAC;QAErF,yCAAyC;QACzC,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YAC3D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,MAAM,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;gBACzC,mBAAmB,EAAE,CAAC;YACxB,CAAC;YAED,qBAAqB;YACrB,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,MAAM,CAAC,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,iBAAiB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;YAE/D,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEzD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE9C,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,QAAQ;YACtB,iBAAiB,EAAE,aAAa;YAChC,YAAY,EAAE;gBACZ,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;gBAClD,kBAAkB,EAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC;gBACnD,eAAe,EAAE,iBAAiB;gBAClC,gBAAgB,EAAE,mBAAmB;aACtC;YACD,kBAAkB,EAAE,cAAc;SACnC,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2DAA2D;QAC3D,MAAM,kBAAkB,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEhD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE9C,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,QAAQ;YACtB,iBAAiB,EAAE,kBAAkB,CAAC,OAAO;YAC7C,YAAY,EAAE;gBACZ,iBAAiB,EAAE,kBAAkB,CAAC,YAAY,CAAC,iBAAiB;gBACpE,kBAAkB,EAAE,kBAAkB,CAAC,YAAY,CAAC,kBAAkB;gBACtE,eAAe,EAAE,kBAAkB,CAAC,YAAY,CAAC,eAAe;gBAChE,gBAAgB,EAAE,kBAAkB,CAAC,YAAY,CAAC,iBAAiB,CAAC,MAAM;aAC3E;YACD,kBAAkB,EAAE,cAAc;SACnC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,GAAQ,EAAE,UAAoC;IACvE,cAAc;IACd,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,mDAAmD;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,kDAAkD;IAClD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAwB,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,YAAY,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,gEAAgE;IAChE,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF Content Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles application/pdf content type. Extracts text and metadata from PDF files,
|
|
5
|
+
* passes all text through the injection pattern registry, and returns sanitized plain text.
|
|
6
|
+
*
|
|
7
|
+
* What it handles:
|
|
8
|
+
* - PDF body text (full document)
|
|
9
|
+
* - PDF metadata: title, author, subject, keywords, creator, producer
|
|
10
|
+
* - Annotation text
|
|
11
|
+
* - Form field values
|
|
12
|
+
*
|
|
13
|
+
* What it strips:
|
|
14
|
+
* - Embedded binary objects (fonts, images, attachments)
|
|
15
|
+
* - Returns only extracted text, not original binary
|
|
16
|
+
*
|
|
17
|
+
* What it passes through:
|
|
18
|
+
* - All extracted text after injection pattern sanitization
|
|
19
|
+
*/
|
|
20
|
+
import type { HandlerResult } from './types.js';
|
|
21
|
+
/**
|
|
22
|
+
* Handle PDF content
|
|
23
|
+
*
|
|
24
|
+
* @param content - Raw PDF binary data as Buffer or string
|
|
25
|
+
* @param mimeType - Original MIME type
|
|
26
|
+
* @returns Sanitized handler result
|
|
27
|
+
*/
|
|
28
|
+
export declare function handlePdf(content: string | Buffer, mimeType: string): Promise<HandlerResult>;
|
|
29
|
+
//# sourceMappingURL=pdf-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-handler.d.ts","sourceRoot":"","sources":["../../src/content-handlers/pdf-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CAwDxB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF Content Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles application/pdf content type. Extracts text and metadata from PDF files,
|
|
5
|
+
* passes all text through the injection pattern registry, and returns sanitized plain text.
|
|
6
|
+
*
|
|
7
|
+
* What it handles:
|
|
8
|
+
* - PDF body text (full document)
|
|
9
|
+
* - PDF metadata: title, author, subject, keywords, creator, producer
|
|
10
|
+
* - Annotation text
|
|
11
|
+
* - Form field values
|
|
12
|
+
*
|
|
13
|
+
* What it strips:
|
|
14
|
+
* - Embedded binary objects (fonts, images, attachments)
|
|
15
|
+
* - Returns only extracted text, not original binary
|
|
16
|
+
*
|
|
17
|
+
* What it passes through:
|
|
18
|
+
* - All extracted text after injection pattern sanitization
|
|
19
|
+
*/
|
|
20
|
+
import { PDFParse } from 'pdf-parse';
|
|
21
|
+
import { sanitize } from '../sanitizer/index.js';
|
|
22
|
+
/**
|
|
23
|
+
* Handle PDF content
|
|
24
|
+
*
|
|
25
|
+
* @param content - Raw PDF binary data as Buffer or string
|
|
26
|
+
* @param mimeType - Original MIME type
|
|
27
|
+
* @returns Sanitized handler result
|
|
28
|
+
*/
|
|
29
|
+
export async function handlePdf(content, mimeType) {
|
|
30
|
+
const startTime = Date.now();
|
|
31
|
+
try {
|
|
32
|
+
// Ensure we have a Buffer
|
|
33
|
+
const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
|
34
|
+
// Parse PDF using pdf-parse v2 API
|
|
35
|
+
const parser = new PDFParse({ data: buffer });
|
|
36
|
+
// Get text and metadata separately
|
|
37
|
+
const textResult = await parser.getText();
|
|
38
|
+
const infoResult = await parser.getInfo();
|
|
39
|
+
// Extract text and metadata
|
|
40
|
+
const bodyText = textResult.text || '';
|
|
41
|
+
const metadata = infoResult.info || {};
|
|
42
|
+
// Build combined text from body + metadata
|
|
43
|
+
let combinedText = bodyText;
|
|
44
|
+
// Append metadata fields
|
|
45
|
+
const metadataFields = ['Title', 'Author', 'Subject', 'Keywords', 'Creator', 'Producer'];
|
|
46
|
+
for (const field of metadataFields) {
|
|
47
|
+
const value = metadata[field];
|
|
48
|
+
if (value && typeof value === 'string') {
|
|
49
|
+
combinedText += `\n\n${field}: ${value}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Pass through injection detection pipeline
|
|
53
|
+
const sanitizationResult = sanitize(combinedText);
|
|
54
|
+
const processingTime = Date.now() - startTime;
|
|
55
|
+
return {
|
|
56
|
+
status: 'sanitized',
|
|
57
|
+
content_type: mimeType,
|
|
58
|
+
sanitized_content: sanitizationResult.content,
|
|
59
|
+
sanitization: {
|
|
60
|
+
patterns_detected: sanitizationResult.sanitization.patterns_detected,
|
|
61
|
+
pii_types_redacted: sanitizationResult.sanitization.pii_types_redacted,
|
|
62
|
+
pii_allowlisted: sanitizationResult.sanitization.pii_allowlisted,
|
|
63
|
+
sanitized_fields: sanitizationResult.sanitization.patterns_detected.length
|
|
64
|
+
},
|
|
65
|
+
processing_time_ms: processingTime
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
status: 'error',
|
|
71
|
+
reason: 'PDF_PARSE_FAILED',
|
|
72
|
+
mime: mimeType,
|
|
73
|
+
message: error instanceof Error ? error.message : String(error)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=pdf-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-handler.js","sourceRoot":"","sources":["../../src/content-handlers/pdf-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAwB,EACxB,QAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEzE,mCAAmC;QACnC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9C,mCAAmC;QACnC,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAE1C,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;QAEvC,2CAA2C;QAC3C,IAAI,YAAY,GAAG,QAAQ,CAAC;QAE5B,yBAAyB;QACzB,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACzF,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvC,YAAY,IAAI,OAAO,KAAK,KAAK,KAAK,EAAE,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QAElD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE9C,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,YAAY,EAAE,QAAQ;YACtB,iBAAiB,EAAE,kBAAkB,CAAC,OAAO;YAC7C,YAAY,EAAE;gBACZ,iBAAiB,EAAE,kBAAkB,CAAC,YAAY,CAAC,iBAAiB;gBACpE,kBAAkB,EAAE,kBAAkB,CAAC,YAAY,CAAC,kBAAkB;gBACtE,eAAe,EAAE,kBAAkB,CAAC,YAAY,CAAC,eAAe;gBAChE,gBAAgB,EAAE,kBAAkB,CAAC,YAAY,CAAC,iBAAiB,CAAC,MAAM;aAC3E;YACD,kBAAkB,EAAE,cAAc;SACnC,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG Content Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles image/svg+xml content type. SVG is XML, not a binary image, and can contain
|
|
5
|
+
* executable code and external references. This handler strips dangerous elements and
|
|
6
|
+
* attributes unconditionally, then sanitizes remaining text content.
|
|
7
|
+
*
|
|
8
|
+
* What it handles:
|
|
9
|
+
* - All text content in SVG elements after stripping dangerous parts
|
|
10
|
+
*
|
|
11
|
+
* What it strips (unconditionally, no attempt to sanitize):
|
|
12
|
+
* - <script> elements and all children
|
|
13
|
+
* - <use> elements with external href or xlink:href attributes
|
|
14
|
+
* - <foreignObject> elements and all children
|
|
15
|
+
* - All event handler attributes (onload, onclick, onerror, etc.)
|
|
16
|
+
* - <set> and <animate> elements that reference external resources
|
|
17
|
+
* - data: URI attributes
|
|
18
|
+
*
|
|
19
|
+
* What it passes through (after injection scan):
|
|
20
|
+
* - Path data (d attribute)
|
|
21
|
+
* - Text elements and their content
|
|
22
|
+
* - <title> and <desc> elements
|
|
23
|
+
* - Presentation attributes (fill, stroke, transform, etc.)
|
|
24
|
+
* - viewBox, width, height attributes
|
|
25
|
+
*/
|
|
26
|
+
import type { HandlerResult } from './types.js';
|
|
27
|
+
/**
|
|
28
|
+
* Handle SVG content
|
|
29
|
+
*
|
|
30
|
+
* @param content - Raw SVG XML string or Buffer
|
|
31
|
+
* @param mimeType - Original MIME type
|
|
32
|
+
* @returns Sanitized handler result
|
|
33
|
+
*/
|
|
34
|
+
export declare function handleSvg(content: string | Buffer, mimeType: string): HandlerResult;
|
|
35
|
+
//# sourceMappingURL=svg-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-handler.d.ts","sourceRoot":"","sources":["../../src/content-handlers/svg-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,aAAa,CAsEf"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG Content Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles image/svg+xml content type. SVG is XML, not a binary image, and can contain
|
|
5
|
+
* executable code and external references. This handler strips dangerous elements and
|
|
6
|
+
* attributes unconditionally, then sanitizes remaining text content.
|
|
7
|
+
*
|
|
8
|
+
* What it handles:
|
|
9
|
+
* - All text content in SVG elements after stripping dangerous parts
|
|
10
|
+
*
|
|
11
|
+
* What it strips (unconditionally, no attempt to sanitize):
|
|
12
|
+
* - <script> elements and all children
|
|
13
|
+
* - <use> elements with external href or xlink:href attributes
|
|
14
|
+
* - <foreignObject> elements and all children
|
|
15
|
+
* - All event handler attributes (onload, onclick, onerror, etc.)
|
|
16
|
+
* - <set> and <animate> elements that reference external resources
|
|
17
|
+
* - data: URI attributes
|
|
18
|
+
*
|
|
19
|
+
* What it passes through (after injection scan):
|
|
20
|
+
* - Path data (d attribute)
|
|
21
|
+
* - Text elements and their content
|
|
22
|
+
* - <title> and <desc> elements
|
|
23
|
+
* - Presentation attributes (fill, stroke, transform, etc.)
|
|
24
|
+
* - viewBox, width, height attributes
|
|
25
|
+
*/
|
|
26
|
+
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
|
|
27
|
+
import { sanitize } from '../sanitizer/index.js';
|
|
28
|
+
/**
|
|
29
|
+
* Handle SVG content
|
|
30
|
+
*
|
|
31
|
+
* @param content - Raw SVG XML string or Buffer
|
|
32
|
+
* @param mimeType - Original MIME type
|
|
33
|
+
* @returns Sanitized handler result
|
|
34
|
+
*/
|
|
35
|
+
export function handleSvg(content, mimeType) {
|
|
36
|
+
const startTime = Date.now();
|
|
37
|
+
// Convert Buffer to string if needed
|
|
38
|
+
const svgString = Buffer.isBuffer(content) ? content.toString('utf-8') : content;
|
|
39
|
+
try {
|
|
40
|
+
// Parse SVG XML
|
|
41
|
+
const parser = new XMLParser({
|
|
42
|
+
ignoreAttributes: false,
|
|
43
|
+
attributeNamePrefix: '@_',
|
|
44
|
+
textNodeName: '#text',
|
|
45
|
+
preserveOrder: false,
|
|
46
|
+
removeNSPrefix: true,
|
|
47
|
+
});
|
|
48
|
+
const parsed = parser.parse(svgString);
|
|
49
|
+
// Track sanitized field count
|
|
50
|
+
let sanitizedFieldCount = 0;
|
|
51
|
+
// Strip dangerous elements and attributes
|
|
52
|
+
const stripped = stripDangerousContent(parsed);
|
|
53
|
+
// Extract all text content for injection scanning
|
|
54
|
+
const textContent = extractTextContent(stripped);
|
|
55
|
+
// Run text through injection detection
|
|
56
|
+
let sanitizationResult;
|
|
57
|
+
if (textContent.length > 0) {
|
|
58
|
+
sanitizationResult = sanitize(textContent);
|
|
59
|
+
if (sanitizationResult.sanitization.content_modified) {
|
|
60
|
+
sanitizedFieldCount = sanitizationResult.sanitization.patterns_detected.length;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Rebuild SVG
|
|
64
|
+
const builder = new XMLBuilder({
|
|
65
|
+
ignoreAttributes: false,
|
|
66
|
+
attributeNamePrefix: '@_',
|
|
67
|
+
textNodeName: '#text',
|
|
68
|
+
format: true,
|
|
69
|
+
suppressEmptyNode: true,
|
|
70
|
+
});
|
|
71
|
+
const sanitizedSvg = builder.build(stripped);
|
|
72
|
+
const processingTime = Date.now() - startTime;
|
|
73
|
+
return {
|
|
74
|
+
status: 'sanitized',
|
|
75
|
+
content_type: mimeType,
|
|
76
|
+
sanitized_content: sanitizedSvg,
|
|
77
|
+
sanitization: {
|
|
78
|
+
patterns_detected: sanitizationResult?.sanitization.patterns_detected || [],
|
|
79
|
+
pii_types_redacted: sanitizationResult?.sanitization.pii_types_redacted || [],
|
|
80
|
+
pii_allowlisted: sanitizationResult?.sanitization.pii_allowlisted || [],
|
|
81
|
+
sanitized_fields: sanitizedFieldCount
|
|
82
|
+
},
|
|
83
|
+
processing_time_ms: processingTime
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
status: 'error',
|
|
89
|
+
reason: 'SVG_PARSE_FAILED',
|
|
90
|
+
mime: mimeType,
|
|
91
|
+
message: error instanceof Error ? error.message : String(error)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Strip dangerous content from parsed SVG
|
|
97
|
+
*
|
|
98
|
+
* Removes:
|
|
99
|
+
* - <script> elements
|
|
100
|
+
* - <foreignObject> elements
|
|
101
|
+
* - <use> with external href
|
|
102
|
+
* - Event handler attributes
|
|
103
|
+
* - <set> and <animate> with external references
|
|
104
|
+
* - data: URIs
|
|
105
|
+
*/
|
|
106
|
+
function stripDangerousContent(node) {
|
|
107
|
+
if (typeof node !== 'object' || node === null) {
|
|
108
|
+
return node;
|
|
109
|
+
}
|
|
110
|
+
// Handle arrays
|
|
111
|
+
if (Array.isArray(node)) {
|
|
112
|
+
return node
|
|
113
|
+
.filter((item) => !shouldRemoveElement(item))
|
|
114
|
+
.map((item) => stripDangerousContent(item));
|
|
115
|
+
}
|
|
116
|
+
// Handle objects
|
|
117
|
+
const result = {};
|
|
118
|
+
for (const [key, value] of Object.entries(node)) {
|
|
119
|
+
// Skip dangerous elements
|
|
120
|
+
if (key === 'script' || key === 'foreignObject') {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// Handle <use> with external href
|
|
124
|
+
if (key === 'use' && typeof value === 'object' && value !== null) {
|
|
125
|
+
const href = value['@_href'] || value['@_xlink:href'];
|
|
126
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://') || href.startsWith('//'))) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Handle <set> and <animate> with external references
|
|
131
|
+
if ((key === 'set' || key === 'animate') && typeof value === 'object' && value !== null) {
|
|
132
|
+
const href = value['@_href'] || value['@_xlink:href'];
|
|
133
|
+
if (href && (href.startsWith('http://') || href.startsWith('https://') || href.startsWith('//'))) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Strip event handler attributes
|
|
138
|
+
if (key.startsWith('@_on')) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Strip data: URIs
|
|
142
|
+
if (typeof value === 'string' && value.startsWith('data:')) {
|
|
143
|
+
result[key] = '';
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
// Strip attributes with data: URIs
|
|
147
|
+
if (key.startsWith('@_') && typeof value === 'string' && value.startsWith('data:')) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Recursively process
|
|
151
|
+
result[key] = stripDangerousContent(value);
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if element should be removed entirely
|
|
157
|
+
*/
|
|
158
|
+
function shouldRemoveElement(element) {
|
|
159
|
+
if (typeof element !== 'object' || element === null) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
// Check for dangerous element types
|
|
163
|
+
const dangerousElements = ['script', 'foreignObject'];
|
|
164
|
+
for (const dangerous of dangerousElements) {
|
|
165
|
+
if (dangerous in element) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Extract all text content from SVG for injection scanning
|
|
173
|
+
*/
|
|
174
|
+
function extractTextContent(node) {
|
|
175
|
+
if (typeof node !== 'object' || node === null) {
|
|
176
|
+
return '';
|
|
177
|
+
}
|
|
178
|
+
if (typeof node === 'string') {
|
|
179
|
+
return node;
|
|
180
|
+
}
|
|
181
|
+
if (Array.isArray(node)) {
|
|
182
|
+
return node.map((item) => extractTextContent(item)).join(' ');
|
|
183
|
+
}
|
|
184
|
+
let text = '';
|
|
185
|
+
for (const [key, value] of Object.entries(node)) {
|
|
186
|
+
// Extract text from text nodes
|
|
187
|
+
if (key === '#text' && typeof value === 'string') {
|
|
188
|
+
text += value + ' ';
|
|
189
|
+
}
|
|
190
|
+
// Extract from title and desc elements (can be string or object)
|
|
191
|
+
if (key === 'title' || key === 'desc') {
|
|
192
|
+
if (typeof value === 'string') {
|
|
193
|
+
text += value + ' ';
|
|
194
|
+
}
|
|
195
|
+
else if (typeof value === 'object') {
|
|
196
|
+
text += extractTextContent(value) + ' ';
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Recursively extract from other children
|
|
200
|
+
if (key !== 'title' && key !== 'desc' && typeof value === 'object') {
|
|
201
|
+
text += extractTextContent(value) + ' ';
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return text.trim();
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=svg-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-handler.js","sourceRoot":"","sources":["../../src/content-handlers/svg-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content Handler Types
|
|
3
|
+
*
|
|
4
|
+
* Shared interfaces for content-type specific handlers.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Success result from a content handler
|
|
8
|
+
*/
|
|
9
|
+
export interface HandlerSuccessResult {
|
|
10
|
+
status: 'sanitized';
|
|
11
|
+
content_type: string;
|
|
12
|
+
sanitized_content: string;
|
|
13
|
+
sanitization: {
|
|
14
|
+
patterns_detected: string[];
|
|
15
|
+
pii_types_redacted: string[];
|
|
16
|
+
pii_allowlisted: Array<{
|
|
17
|
+
type: string;
|
|
18
|
+
value: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
}>;
|
|
21
|
+
sanitized_fields: number;
|
|
22
|
+
};
|
|
23
|
+
processing_time_ms: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Error result from a content handler
|
|
27
|
+
*/
|
|
28
|
+
export interface HandlerErrorResult {
|
|
29
|
+
status: 'error' | 'rejected';
|
|
30
|
+
reason: string;
|
|
31
|
+
mime: string;
|
|
32
|
+
message: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Union type for all handler results
|
|
36
|
+
*/
|
|
37
|
+
export type HandlerResult = HandlerSuccessResult | HandlerErrorResult;
|
|
38
|
+
/**
|
|
39
|
+
* Content handler function signature
|
|
40
|
+
*/
|
|
41
|
+
export type ContentHandler = (content: string | Buffer, mimeType: string) => Promise<HandlerResult> | HandlerResult;
|
|
42
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/content-handlers/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE;QACZ,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxE,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/content-handlers/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
* Maps injection pattern categories to compliance framework identifiers:
|
|
5
5
|
* - OWASP LLM Top 10 (2025)
|
|
6
6
|
* - NIST AI 600-1 (Generative AI Profile)
|
|
7
|
+
* - NIST AI RMF (AI Risk Management Framework - AI 100-1)
|
|
8
|
+
* - NIST CSF 2.0 (Cybersecurity Framework 2.0)
|
|
7
9
|
* - MITRE ATLAS (Adversarial Threat Landscape for AI Systems)
|
|
8
10
|
* - ISO/IEC 42001:2023 (AI Management System - Annex A Controls)
|
|
9
11
|
*/
|
|
10
12
|
export interface FrameworkMappings {
|
|
11
13
|
owasp_llm: string;
|
|
12
14
|
nist_ai_600_1: string;
|
|
15
|
+
nist_ai_rmf: string;
|
|
16
|
+
nist_csf_2_0: string;
|
|
13
17
|
mitre_atlas: string;
|
|
14
18
|
iso_42001: string;
|
|
15
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-mapper.d.ts","sourceRoot":"","sources":["../../src/sanitizer/framework-mapper.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"framework-mapper.d.ts","sourceRoot":"","sources":["../../src/sanitizer/framework-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAicD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,iBAAiB,CAE/E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CASjD"}
|