@optilogic/core 1.2.0 → 1.2.2
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/dist/index.cjs +66 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +66 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/file-view/components/HtmlRenderer.tsx +110 -2
package/dist/index.d.cts
CHANGED
|
@@ -2968,7 +2968,24 @@ declare namespace CsvRenderer {
|
|
|
2968
2968
|
/**
|
|
2969
2969
|
* HtmlRenderer
|
|
2970
2970
|
*
|
|
2971
|
-
* Renders HTML content in a
|
|
2971
|
+
* Renders HTML content in a triple-locked iframe:
|
|
2972
|
+
*
|
|
2973
|
+
* Layer 1 — `sandbox="allow-scripts"` (no allow-same-origin):
|
|
2974
|
+
* Opaque origin. No access to parent DOM, cookies, localStorage,
|
|
2975
|
+
* sessionStorage, or IndexedDB. No form submission, popups,
|
|
2976
|
+
* top-navigation, or pointer-lock.
|
|
2977
|
+
*
|
|
2978
|
+
* Layer 2 — Content-Security-Policy (iframe `csp` attr + meta fallback):
|
|
2979
|
+
* Blocks ALL network requests (fetch, XHR, WebSocket, sendBeacon,
|
|
2980
|
+
* image pings, external scripts/styles/fonts). Only inline scripts,
|
|
2981
|
+
* inline styles, and data:/blob: images are allowed.
|
|
2982
|
+
*
|
|
2983
|
+
* Layer 3 — Permissions-Policy via `allow` attribute:
|
|
2984
|
+
* Explicitly denies every device/sensor API (camera, microphone,
|
|
2985
|
+
* geolocation, payment, USB, display-capture, etc.).
|
|
2986
|
+
*
|
|
2987
|
+
* Additional hardening:
|
|
2988
|
+
* - referrerpolicy="no-referrer" — no URL leakage to embedded content
|
|
2972
2989
|
*/
|
|
2973
2990
|
declare function HtmlRenderer({ content, fileName, className, }: FileRendererProps): react_jsx_runtime.JSX.Element;
|
|
2974
2991
|
declare namespace HtmlRenderer {
|
package/dist/index.d.ts
CHANGED
|
@@ -2968,7 +2968,24 @@ declare namespace CsvRenderer {
|
|
|
2968
2968
|
/**
|
|
2969
2969
|
* HtmlRenderer
|
|
2970
2970
|
*
|
|
2971
|
-
* Renders HTML content in a
|
|
2971
|
+
* Renders HTML content in a triple-locked iframe:
|
|
2972
|
+
*
|
|
2973
|
+
* Layer 1 — `sandbox="allow-scripts"` (no allow-same-origin):
|
|
2974
|
+
* Opaque origin. No access to parent DOM, cookies, localStorage,
|
|
2975
|
+
* sessionStorage, or IndexedDB. No form submission, popups,
|
|
2976
|
+
* top-navigation, or pointer-lock.
|
|
2977
|
+
*
|
|
2978
|
+
* Layer 2 — Content-Security-Policy (iframe `csp` attr + meta fallback):
|
|
2979
|
+
* Blocks ALL network requests (fetch, XHR, WebSocket, sendBeacon,
|
|
2980
|
+
* image pings, external scripts/styles/fonts). Only inline scripts,
|
|
2981
|
+
* inline styles, and data:/blob: images are allowed.
|
|
2982
|
+
*
|
|
2983
|
+
* Layer 3 — Permissions-Policy via `allow` attribute:
|
|
2984
|
+
* Explicitly denies every device/sensor API (camera, microphone,
|
|
2985
|
+
* geolocation, payment, USB, display-capture, etc.).
|
|
2986
|
+
*
|
|
2987
|
+
* Additional hardening:
|
|
2988
|
+
* - referrerpolicy="no-referrer" — no URL leakage to embedded content
|
|
2972
2989
|
*/
|
|
2973
2990
|
declare function HtmlRenderer({ content, fileName, className, }: FileRendererProps): react_jsx_runtime.JSX.Element;
|
|
2974
2991
|
declare namespace HtmlRenderer {
|
package/dist/index.js
CHANGED
|
@@ -7450,18 +7450,82 @@ function CsvRenderer({ content, className }) {
|
|
|
7450
7450
|
) });
|
|
7451
7451
|
}
|
|
7452
7452
|
CsvRenderer.displayName = "CsvRenderer";
|
|
7453
|
+
var CSP_POLICY = [
|
|
7454
|
+
"default-src 'none'",
|
|
7455
|
+
"script-src 'unsafe-inline'",
|
|
7456
|
+
"style-src 'unsafe-inline'",
|
|
7457
|
+
"img-src data: blob:"
|
|
7458
|
+
].join("; ");
|
|
7459
|
+
var PERMISSIONS_POLICY = [
|
|
7460
|
+
"camera=()",
|
|
7461
|
+
"microphone=()",
|
|
7462
|
+
"geolocation=()",
|
|
7463
|
+
"payment=()",
|
|
7464
|
+
"usb=()",
|
|
7465
|
+
"clipboard-read=()",
|
|
7466
|
+
"clipboard-write=()",
|
|
7467
|
+
"display-capture=()",
|
|
7468
|
+
"fullscreen=()",
|
|
7469
|
+
"autoplay=()",
|
|
7470
|
+
"web-share=()",
|
|
7471
|
+
"screen-wake-lock=()",
|
|
7472
|
+
"xr-spatial-tracking=()",
|
|
7473
|
+
"magnetometer=()",
|
|
7474
|
+
"gyroscope=()",
|
|
7475
|
+
"accelerometer=()"
|
|
7476
|
+
].join(", ");
|
|
7477
|
+
function buildSandboxedHtml(content) {
|
|
7478
|
+
return `<!DOCTYPE html>
|
|
7479
|
+
<html>
|
|
7480
|
+
<head>
|
|
7481
|
+
<meta http-equiv="Content-Security-Policy" content="${CSP_POLICY}">
|
|
7482
|
+
<script>
|
|
7483
|
+
// Neutralise APIs that the sandbox + CSP can't fully block.
|
|
7484
|
+
// This runs in <head> before any user content in <body>.
|
|
7485
|
+
// Uses Object.defineProperty to make overrides non-configurable
|
|
7486
|
+
// so user scripts cannot restore the original via prototype tricks.
|
|
7487
|
+
(function(){
|
|
7488
|
+
// postMessage: iframe can message parent even without allow-same-origin.
|
|
7489
|
+
// Kill it so content can't probe or spam any future parent listeners.
|
|
7490
|
+
// Also kill parent/top refs as an extra layer.
|
|
7491
|
+
var noop = function(){};
|
|
7492
|
+
try { Object.defineProperty(window, 'postMessage', { value: noop, writable: false, configurable: false }); } catch(e) {}
|
|
7493
|
+
try { Object.defineProperty(window, 'parent', { value: window, writable: false, configurable: false }); } catch(e) {}
|
|
7494
|
+
try { Object.defineProperty(window, 'top', { value: window, writable: false, configurable: false }); } catch(e) {}
|
|
7495
|
+
try { Object.defineProperty(window, 'opener', { value: null, writable: false, configurable: false }); } catch(e) {}
|
|
7496
|
+
|
|
7497
|
+
// RTCPeerConnection: not governed by CSP; could contact a STUN server
|
|
7498
|
+
// over UDP to leak the user's IP. Kill all browser-prefixed variants.
|
|
7499
|
+
var rtcNames = ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection'];
|
|
7500
|
+
for (var i = 0; i < rtcNames.length; i++) {
|
|
7501
|
+
try { Object.defineProperty(window, rtcNames[i], { value: undefined, writable: false, configurable: false }); } catch(e) {}
|
|
7502
|
+
}
|
|
7503
|
+
})();
|
|
7504
|
+
</script>
|
|
7505
|
+
</head>
|
|
7506
|
+
<body>${content}</body>
|
|
7507
|
+
</html>`;
|
|
7508
|
+
}
|
|
7453
7509
|
function HtmlRenderer({
|
|
7454
7510
|
content,
|
|
7455
7511
|
fileName,
|
|
7456
7512
|
className
|
|
7457
7513
|
}) {
|
|
7514
|
+
const srcDoc = React20.useMemo(
|
|
7515
|
+
() => buildSandboxedHtml(content ?? ""),
|
|
7516
|
+
[content]
|
|
7517
|
+
);
|
|
7518
|
+
const iframeProps = { csp: CSP_POLICY };
|
|
7458
7519
|
return /* @__PURE__ */ jsx(
|
|
7459
7520
|
"iframe",
|
|
7460
7521
|
{
|
|
7461
|
-
srcDoc
|
|
7522
|
+
srcDoc,
|
|
7462
7523
|
sandbox: "allow-scripts",
|
|
7463
7524
|
title: fileName,
|
|
7464
|
-
|
|
7525
|
+
referrerPolicy: "no-referrer",
|
|
7526
|
+
allow: PERMISSIONS_POLICY,
|
|
7527
|
+
className: cn("h-full w-full border-0", className),
|
|
7528
|
+
...iframeProps
|
|
7465
7529
|
}
|
|
7466
7530
|
);
|
|
7467
7531
|
}
|