Files
tkmind_go/ui/h5/mindspace-scan.mjs
john 4e21ca937a
Deploy Documentation / deploy (push) Has been cancelled
Canary / Prepare Version (push) Has been cancelled
Canary / build-cli (push) Has been cancelled
Canary / Upload Install Script (push) Has been cancelled
Canary / bundle-desktop (push) Has been cancelled
Canary / bundle-desktop-intel (push) Has been cancelled
Canary / bundle-desktop-linux (push) Has been cancelled
Canary / bundle-desktop-windows (push) Has been cancelled
Canary / bundle-desktop-windows-cuda (push) Has been cancelled
Canary / Release (push) Has been cancelled
Unused Dependencies / machete (push) Has been cancelled
CI / changes (push) Has been cancelled
CI / Check Rust Code Format (push) Has been cancelled
CI / Build and Test Rust Project (push) Has been cancelled
CI / Build Rust Project on Windows (push) Has been cancelled
CI / Check MSRV (push) Has been cancelled
CI / Lint Rust Code (push) Has been cancelled
CI / Check Generated Schemas are Up-to-Date (push) Has been cancelled
CI / Test and Lint Electron Desktop App (push) Has been cancelled
CI / H5 Plaza Tests and Build (push) Has been cancelled
Live Provider Tests / check-fork (push) Has been cancelled
Live Provider Tests / changes (push) Has been cancelled
Live Provider Tests / Build Binary (push) Has been cancelled
Live Provider Tests / Smoke Tests (push) Has been cancelled
Live Provider Tests / Smoke Tests (Code Execution) (push) Has been cancelled
Live Provider Tests / Compaction Tests (push) Has been cancelled
Live Provider Tests / goose server HTTP integration tests (push) Has been cancelled
Publish Ask AI Bot Docker Image / docker (push) Has been cancelled
Publish Docker Image / docker (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Add TKMind platform extensions, H5/MindSpace stack, and deployment tooling.
Fork goose with custom MCP widgets, platform extensions (aider, git, web, search),
MindSpace H5 backend/frontend, Plaza/Ops UIs, and deploy scripts for tkmind.cn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 21:30:20 +08:00

108 lines
2.8 KiB
JavaScript

const SCRIPT_PATTERNS = [
/<script\b/i,
/javascript:/i,
/\bon\w+\s*=/i,
/<iframe\b/i,
/<object\b/i,
/<embed\b/i,
];
const MAX_ZIP_COMPRESSION_RATIO = 100;
const MAX_ZIP_LOCAL_HEADERS = 512;
function isZipContainer(mimeType) {
return (
mimeType.includes('openxmlformats') ||
mimeType.includes('msword') ||
mimeType.includes('ms-excel') ||
mimeType.includes('ms-powerpoint')
);
}
function scanTextContent(buffer) {
const sample = buffer.subarray(0, Math.min(buffer.length, 256 * 1024)).toString('utf8');
for (const pattern of SCRIPT_PATTERNS) {
if (pattern.test(sample)) {
return {
scanStatus: 'blocked',
riskLevel: 'high',
findings: ['text_active_content'],
};
}
}
return null;
}
function scanZipStructure(buffer) {
if (buffer.subarray(0, 2).toString('ascii') !== 'PK') {
return {
scanStatus: 'blocked',
riskLevel: 'medium',
findings: ['zip_signature_mismatch'],
};
}
let offset = 0;
let headers = 0;
while (offset + 30 <= buffer.length && headers < MAX_ZIP_LOCAL_HEADERS) {
if (buffer.subarray(offset, offset + 2).toString('ascii') !== 'PK') break;
const compressionMethod = buffer.readUInt16LE(offset + 8);
const compressedSize = buffer.readUInt32LE(offset + 18);
const uncompressedSize = buffer.readUInt32LE(offset + 22);
const nameLength = buffer.readUInt16LE(offset + 26);
const extraLength = buffer.readUInt16LE(offset + 28);
const headerSize = 30 + nameLength + extraLength;
if (headerSize <= 0 || offset + headerSize > buffer.length) break;
if (compressionMethod !== 0 && compressedSize > 0 && uncompressedSize / compressedSize > MAX_ZIP_COMPRESSION_RATIO) {
return {
scanStatus: 'blocked',
riskLevel: 'critical',
findings: ['zip_bomb_ratio'],
};
}
headers += 1;
offset += headerSize;
if (compressedSize > 0) {
offset += compressedSize;
}
}
return null;
}
export function runBasicFileScan(buffer, { filename, mimeType }) {
if (!Buffer.isBuffer(buffer) || buffer.length === 0) {
return {
scanStatus: 'blocked',
riskLevel: 'high',
findings: ['empty_file'],
};
}
if (mimeType.startsWith('text/') || mimeType === 'application/pdf') {
const textFinding = scanTextContent(buffer);
if (textFinding) return textFinding;
}
if (mimeType === 'application/pdf' && buffer.subarray(0, 5).toString('ascii') !== '%PDF-') {
return {
scanStatus: 'blocked',
riskLevel: 'medium',
findings: ['pdf_signature_mismatch'],
};
}
if (isZipContainer(mimeType)) {
const zipFinding = scanZipStructure(buffer);
if (zipFinding) return zipFinding;
}
return {
scanStatus: 'passed',
riskLevel: 'none',
findings: [],
};
}