[object Object]

← back to Rentv

chore(desk): sandbox the inline preview iframe + pvClose onload guard (v0.23.1)

4188cba0afa4b091a35b6dd502f36b131c8548d6 · 2026-08-12 16:26:29 -0700 · Steve

Security hardening from the session-close review (2 independent reviewers, no
CRITICAL found): bound the preview iframe with sandbox= to block top-frame
navigation by framed third-party pages (DRE/assessor/broker sites); clear the
load timeout + null onload at the top of pvClose for lifecycle symmetry with
pvOpen. Verified: inline render + Maps embed + blocked fallback all still pass.

Files touched

Diff

commit 4188cba0afa4b091a35b6dd502f36b131c8548d6
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 12 16:26:29 2026 -0700

    chore(desk): sandbox the inline preview iframe + pvClose onload guard (v0.23.1)
    
    Security hardening from the session-close review (2 independent reviewers, no
    CRITICAL found): bound the preview iframe with sandbox= to block top-frame
    navigation by framed third-party pages (DRE/assessor/broker sites); clear the
    load timeout + null onload at the top of pvClose for lifecycle symmetry with
    pvOpen. Verified: inline render + Maps embed + blocked fallback all still pass.
---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 public/desk.html  | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index db521f48..bfcc0b93 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "rentv",
-  "version": "0.22.0",
+  "version": "0.23.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "rentv",
-      "version": "0.22.0",
+      "version": "0.23.1",
       "dependencies": {
         "express": "^4.21.2",
         "pg": "^8.22.0"
diff --git a/package.json b/package.json
index 24a9ce8b..37a21975 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "rentv",
-  "version": "0.23.0",
+  "version": "0.23.1",
   "private": true,
   "main": "server.js",
   "scripts": {
diff --git a/public/desk.html b/public/desk.html
index 4eccaa11..e341c2d1 100644
--- a/public/desk.html
+++ b/public/desk.html
@@ -120,7 +120,7 @@
       <div class="sm">Some sites (LinkedIn, Google, Facebook/X) refuse to load inside an embedded frame for security. Open it in a new tab instead — it'll still keep the desk here behind it.</div>
       <a class="open" id="pvBlockOpen" href="#" target="_blank" rel="noopener noreferrer">Open in new tab ↗</a>
     </div>
-    <iframe id="pvFrame" referrerpolicy="strict-origin-when-cross-origin" allow="fullscreen"></iframe>
+    <iframe id="pvFrame" referrerpolicy="strict-origin-when-cross-origin" allow="fullscreen" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"></iframe>
   </div>
 </aside>
 <script>
@@ -181,7 +181,7 @@ function pvEmbed(u){ // upgrade a plain Google Maps search into a keyless embedd
 // Skip the iframe attempt entirely and show the "open in tab" fallback immediately (no blank frame, no wait).
 const PV_HARD=[/google\.[a-z.]+\/search/i,/linkedin\.com/i,/facebook\.com/i,/(^|\/\/)(www\.)?(x|twitter)\.com/i,/instagram\.com/i];
 function pvHardBlocked(u){return PV_HARD.some(re=>re.test(u));}
-function pvClose(){$('pv').classList.remove('open');$('pvScrim').classList.remove('open');$('pv').setAttribute('aria-hidden','true');$('pvFrame').src='about:blank';clearTimeout(PV.t);$('pvBody').classList.remove('loading','blocked');}
+function pvClose(){clearTimeout(PV.t);$('pvFrame').onload=null;$('pv').classList.remove('open');$('pvScrim').classList.remove('open');$('pv').setAttribute('aria-hidden','true');$('pvFrame').src='about:blank';$('pvBody').classList.remove('loading','blocked');}
 function pvOpen(href,label){
   const body=$('pvBody'),fr=$('pvFrame');
   $('pvTitle').textContent=label||'Preview';

← 2eeec581 CRM: complete LABJ2026 import — 1,639 contacts across 52 lis  ·  back to Rentv  ·  auto-data-snapshot: 2026-08-12T16:33:05 (7 data files) — dat 14cfd3dd →