Is Just-One-Page-PDF: An awesome web page to PDF tool safe?

Medium risk

Just-One-Page-PDF: An awesome web page to PDF tool is medium risk. Starting a page-to-PDF capture uses the manage-extensions permission. The worker scans the page for extension iframes, matches IDs against enabled installed extensions, disables matches during capture, stores IDs, and later…

suziwen1v1.9.4Chrome Web Store
45Risk

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Disables Other Extensions During PDF Capture

Starting a page-to-PDF capture uses the manage-extensions permission.

The worker scans the page for extension iframes, matches IDs against enabled installed extensions, disables matches during capture, stores IDs, and later re-enables them.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You start a page-to-PDF capture.

The extension did this

The extension scans the page for extension iframes, turns matching enabled extensions off during capture, stores their IDs locally, and later tries to turn them back on.

02EvidenceFIELD TABLE
Concrete values used by the extension-management path
FieldValueWhy it matters
Permission to manage extensions
manifest permissions includes "management"This permission lets the extension turn other installed extensions on or off.
Extension iframe URL
chrome-extension://cjpalhdlnbpafiamejdnhcphjbkeiagm/frame.html (illustrative)This is how the page scan identifies that another browser extension has injected a frame into the page.
Matched extension ID
cjpalhdlnbpafiamejdnhcphjbkeiagm (illustrative)The ID is compared with enabled installed extensions before the extension is turned off.
Local restore list
chrome.storage.local disableExtensionIdsThis local value records which extensions were turned off so the extension can try to restore them after capture.
Disable and restore values
setEnabled(id, false) then setEnabled(id, true)The first value turns the matched extension off; the later value attempts to turn it back on.
03EvidenceCORRESPONDENCE
Where the capture flow invokes extension disable and restore
WhenYou didExtension did
before capture
content_script
The page-capture script sends a create request.
service_worker
The service worker enters the PDF creation path and scans for extension iframes before capture.
during setup
service_worker
The scan returns IDs that match enabled installed extensions.
extension
Each matching extension is turned off and the IDs are saved locally.
after capture
service_worker
The capture path finishes or reaches a later frame-ready path.
extension
The saved IDs are read back and the extension attempts to turn those extensions on again.
04EvidenceCODE COMPARE
The code that does this

Shipped code that scans, disables, stores, and restores extension IDs

What it actually does
Readable scanner functionjs/background.js
_w = function(e) {
  const t = [],
    n = (r, i = 1, o) => {
      if (i > 10) return "function" == typeof r.remove && e && r.remove(), void(o && "function" == typeof o.remove && o.remove());
      i++;
      let a = !1;
      r.querySelectorAll("*").forEach((function(r) {
        if (!a)
          if ("IFRAME" === r.tagName)(function(n) {
            if (n.src.startsWith("chrome-extension://")) {
              let r = n.src;
              if (r = r.substring(19), r = r.split("/")[0], r && t.push(r), e) return n.remove(), !0
            }
          })(r) && o && "function" == typeof o.remove && (o.remove(), a = !0);
          else if (r.shadowRoot) n(r.shadowRoot, i);
        else try {
          const e = chrome.dom.openOrClosedShadowRoot(r);
          e && n(e, i, r)
        } catch (e) {}
      }))
    };
  return n(document), t
}
Readable disable functionjs/background.js
Sw = async function(e) {
  if (!pb.checkCanExecuteScript(e)) return [];
  const t = e.id,
    n = await chrome.scripting.executeScript({
      target: {
        tabId: t,
        allFrames: !0
      },
      injectImmediately: !0,
      func: _w
    }),
    r = [],
    i = (await chrome.management.getAll()).filter((e => "extension" === e.type && (e.id !== chrome.runtime.id && !!e.enabled))).map((e => e.id));
  if (n && n.forEach((e => {
      e.result?.forEach((e => {
        e != chrome.runtime.id && i.indexOf(e) >= 0 && r.push(e)
      }))
    })), r.length > 0) {
    const e = Array.from(new Set(r));
    for (let t = 0; t < e.length; t++) {
      const n = e[t];
      try {
        await chrome.management.setEnabled(n, !1)
      } catch (e) {}
    }
    const n = (await chrome.storage.local.get("disableExtensionIds")).disableExtensionIds || [],
      i = Array.from(new Set(e.concat(n)));
    return await chrome.storage.local.set({
      disableExtensionIds: i
    }), await chrome.scripting.executeScript({
      target: {
        tabId: t,
        allFrames: !0
      },
      func: _w,
      args: [!0]
    }), e
  }
  return []
}
Readable restore functionjs/background.js
kw = async function(e, t) {
  const n = (await chrome.storage.local.get("disableExtensionIds")).disableExtensionIds || [];
  t = Array.from(new Set(n.concat(t)));
  for (let e = 0; e < t.length; e++) {
    const n = t[e];
    try {
      await chrome.management.setEnabled(n, !0)
    } catch (e) {}
  }
  await chrome.storage.local.set({
    disableExtensionIds: []
  })
}
05EvidenceCODE COMPARE
The code that does this

Manifest permission that enables the behavior

What it actually does
"permissions": [
  "activeTab",
  "contextMenus",
  "scripting",
  "debugger",
  "downloads",
  "storage",
  "management",
  "tabs",
  "notifications",
  "history"
]
Updated 17 September 2026fgbhbfdgdlojklkbhdoilkdlomoilbpl