Is Web to PDF safe?
We analyzed Web to PDF version 3.4.8's actual code and gave it a 62/100 trust score. Useful PDF features come with unusually broad page access, powerful…
Bottom line
Useful PDF features come with unusually broad page access, powerful debugger control, and persistent usage reporting.
What it can access
It can inspect and alter visible content on every website and use powerful debugger controls for PDF creation, broader than an on-demand converter needs. [Q1][Q2]
Security weaknesses
All-site access and debugger power create meaningful exposure if the extension or its controls are misused, though privileged commands are internally restricted. [Q1][Q21]
Signs of misuse
It sends exported-site domains and device metadata with a persistent ID, while public PDF sharing is user initiated. [Q6][Q13][Q14]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It requests access to every website, all tab URLs, script injection, Chrome's debugger, storage, and Google identity. Printing a page and optionally sharing it to Drive explains most of these powers, but permanent all-site page access are broader than necessary for an on-demand converter, and debugger access is exceptionally powerful.
Declares tabs, scripting, debugger, storage, identity, <all_urls>, all-site scripts, and the Google Drive drive.file OAuth scope. — manifest.json:permissions, host_permissions, content_scripts, oauth2
Attaches Chrome debugger and uses Page.printToPDF after a user starts an export. — background.js:OE/UE/HE PDF generation flow
Pings or injects the full content-script set into supported activated pages, in addition to the manifest's all-site registration. — background.js:XE/ZE tab-activation flow
Which websites can it run on, and can it read or change what appears on those pages?
It runs on all ordinary HTTP and HTTPS pages. Its export tools inspect page structure, text, layout, and styles; hide or resize elements; scroll through lazy-loaded content; and temporarily alter article, selected-element, Reddit, Pikabu, ChatGPT, Gemini, and DeepSeek views before printing.
Registers five JavaScript content scripts and three style sheets on <all_urls>. — manifest.json:content_scripts
Queries and temporarily restyles page elements for full-page, article, element, and conversation exports. — content-scripts/print.js:GS/KS export-mode dispatch and page-specific handlers
Lets the user hide arbitrary page elements before export and supports local undo. — content-scripts/RemovalMode.js:removal-mode click handler
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
Its all-site page access can inspect the rendered page, and Chrome's print-to-PDF output can include messages, account data, and values visibly present in form controls. The code does not install a keystroke logger or specifically harvest passwords, but users should assume anything visible in an exported page can enter the local PDF.
Grants extension scripts DOM access on every ordinary site. — manifest.json:content_scripts and host_permissions
Directly locates and prepares private chat conversation containers and arbitrary selected elements for export. — content-scripts/print.js:conversation and DOM export handlers
Prints the current rendered tab state, which can contain visible filled fields and private page content. — background.js:UE Page.printToPDF
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
It does not request cookies, saved browser history, bookmarks, or download-management access. It does read tab URLs and keeps its own local conversion history containing each exported page's URL, title, PDF, settings, size, mode, and time.
Requests tabs and identity, but not cookies, history, bookmarks, or downloads; OAuth scope is drive.file. — manifest.json:permissions and oauth2
Stores source URL, title, PDF blob, export settings, user profile, size, and creation time in local IndexedDB, retaining up to 100 records. — background.js:SE and yE PDF-store functions
Obtains an interactive OAuth token and operates on a dedicated Drive folder and files it creates. — chunks/DownloadButton-CTk3AwRh.js:Pe Google Drive client
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
It can write a generated public link to the clipboard after a click, and it can upload generated PDFs to the user's Google Drive with interactive authorization. Users may separately grant access to file:// pages in browser settings.
Uses navigator.clipboard.writeText and Google identity/Drive APIs only from explicit share controls. — chunks/DownloadButton-CTk3AwRh.js:ShareButton and Pe Drive client
Allows file URLs only when browser-level file-scheme access has been granted. — background.js:JE/qE supported-page checks
No geolocation, camera, microphone, nativeMessaging, clipboardRead, or management permission is declared. — manifest.json:permissions
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
After every successful export it sends Amplitude a persistent user ID, the exported site's domain, export mode and settings, print parameters, PDF size, browser version/user agent, language, install date, app-rating state, preferences, and the request's network address. Better Stack receives explicit error reports tied to that ID and diagnostic context.
POSTs pdf_exported to api2.amplitude.com with user_id, domain, mode, settings, print parameters, file size, user agent, language, install date, rating, and preferences; ip is set to $remote. — background.js:cE Amplitude export event
Sends captured exceptions to a Better Stack Sentry-compatible endpoint after assigning the persistent profile ID and optional diagnostic extras. — background.js:aE error reporter
POSTs license validation, details, recovery, checkout, customer portal, and paywall-decision data to money.webtopdf.space. — chunks/api-Cw_K5pGB.js:complete module
Uploads the entire PDF to Google Drive only after the user requests a public link. — chunks/DownloadButton-CTk3AwRh.js:ShareButton
Does it download or run code, settings, or instructions supplied by a remote server?
It does not download executable code. It does consume remote license validation, country, price, checkout, and paywall decisions from its billing services, which affect feature access and prompts but do not become JavaScript or page commands.
POSTs local license/platform data and parses JSON decisions, prices, checkout URLs, and account status from money.webtopdf.space. — chunks/api-Cw_K5pGB.js:paywall and license API functions
Uses the remote paywall response after local trial actions are exhausted. — chunks/DownloadButton-CTk3AwRh.js:ml paywall flow
All executable scripts are packaged locally; MV3 extension pages do not load remote scripts. — manifest.json:extension entry points
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
Installation automatically opens the vendor's welcome page and registers an uninstall survey URL. page access load on supported sites and the background pings or reinjects them as tabs are activated.
Opens https://webtopdf.space/welcome on install and sets a Google Forms uninstall URL. — background.js:_c/vc install handlers
Contacts or injects packaged content scripts when supported tabs become active. — background.js:XE/ZE tab activation handlers
Creates the PDF and sends export telemetry only after the internal CREATE_AND_OPEN_PDF command. — background.js:HE/cE PDF flow
Can it change important browser settings, including your proxy, search engine, homepage, privacy settings, or other extensions?
No evidence of this behavior was found in the reviewed package.
Does not request proxy, management, privacy, or settings permissions. — manifest.json:permissions
Debugger use is limited to PDF rendering and temporary emulation settings for the selected tab. — background.js:privileged API review
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
Important behavior is distributed across several very large one-line minified bundles with shortened identifiers and duplicated frameworks. The code is not encrypted or deliberately packed, and key flows remain traceable, but reviewing all-site scripts, telemetry, PDF generation, and sharing is substantially harder than with source-mapped first-party code.
Roughly 900 KB minified bundle containing storage, telemetry, PDF libraries, and privileged command routing. — background.js:entire file
Roughly 1.46 MB minified content script containing page-selection and export preparation behavior. — content-scripts/SelectionMode.js:entire file
Roughly 1.46 MB minified content script; no source maps were packaged. — content-scripts/print.js:entire file
Does it use eval(), new Function(), or string-based timers to turn text into executable code?
The background invokes Chrome Debugger Protocol Runtime.evaluate with a fixed packaged expression that only calculates page height. Bundled compatibility code also contains a Function('return this') fallback after checking globalThis/window/self/global, so that fallback is not reached in modern Chrome.
Runs a fixed local Runtime.evaluate expression to measure document height for PDF sizing. — background.js:DE page-height helper
Contains Function('return this') as a last-resort legacy fallback after modern global-object checks. — pdfjs/pdf.worker.legacy.min.mjs:core-js global-object helper
No remote response, page text, or telemetry value reaches Runtime.evaluate or a Function constructor. — background.js:network and dynamic-code data-flow review
Does it track the websites, pages, searches, or links you visit?
No evidence of this behavior was found in the reviewed package.
Stores each converted page's full URL and title with the generated PDF and timestamp in IndexedDB. — background.js:SE local PDF record
Extracts new URL(pdf.url).hostname and sends that domain with user_id whenever a PDF is exported. — background.js:cE Amplitude event
Adds a persistent user ID and caller-supplied operational context to Better Stack error reports. — background.js:aE error handling
Does it create a persistent ID or browser fingerprint to recognize you?
It creates a random UUID-like installation ID in synchronized extension storage and uses it as the Amplitude user_id and Better Stack error-report user ID. It additionally sends user agent, language, install date, and preference metadata with export events.
Creates meta.id with crypto.randomUUID, stores it in sync:userProfile, and retains install date and app settings. — background.js:mc/gc userProfile functions
Assigns profile.meta.id to user_id and includes browser, language, install date, rating, and preferences. — background.js:cE Amplitude event
Calls setUser with the same stored ID before sending an exception. — background.js:aE error reporter
Does it send cookies, session details, authentication data, or page contents elsewhere?
It does not read or send browser cookies or session tokens, and ordinary exports remain local. When the user chooses Share and then creates a public link, it uploads the complete generated PDF—which may contain private page contents—to a Web to PDF folder in Google Drive and grants anyone-with-link reader access.
After a click, uploads pdf.data, calls makePublic, retrieves the webViewLink, and presents it to the user. — chunks/DownloadButton-CTk3AwRh.js:ShareButton x function
Creates a Google Drive permission with role reader and type anyone. — chunks/DownloadButton-CTk3AwRh.js:Pe.makePublic
Default generation stores the PDF locally and sends only metadata—not the PDF bytes—to Amplitude. — background.js:HE/SE/cE flow
Does it record typing, form entries, clipboard contents, or screenshots?
It does not log keystrokes or read clipboard contents. A user-requested print-to-PDF operation records the rendered page and can therefore preserve visible form values, chats, and other private screen content in the local PDF.
Captures the rendered page into a PDF after the export command. — background.js:UE Page.printToPDF
Deliberately prepares visible private conversations or selected DOM regions for inclusion in the PDF. — content-scripts/print.js:chatgpt/gemini/deepseek and selected-element handlers
Writes only the generated public URL to the clipboard; it never reads clipboard data. — chunks/DownloadButton-CTk3AwRh.js:ShareButton copy handler
Can a website or remote server send commands that make the extension take actions?
Pages under *.webtopdf.space can externally ask the extension to save a supplied license key, and the vendor services controls license and paywall decisions. These remote inputs affect billing state only; they cannot invoke PDF generation, debugger actions, arbitrary script injection, or Google Drive sharing.
Allows external extension messages from https://*.webtopdf.space/*. — manifest.json:externally_connectable
Accepts only SAVE_LICENSE_KEY, trims the supplied string, stores it, and notifies packaged extension UI. — background.js:$E onMessageExternal handler
Consumes remote JSON decisions for license, country, prices, checkout, and account operations. — chunks/api-Cw_K5pGB.js:paywall/license functions
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Only hides user-selected elements with inline display:none and retains their prior style for undo. — content-scripts/RemovalMode.js:removal-mode handler
Temporary changes prepare a printable layout and are restored in the export cleanup flow. — content-scripts/print.js:style manager and export handlers
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
No evidence of this behavior was found in the reviewed package.
No webRequest, declarativeNetRequest, proxy, or downloads permission is declared. — manifest.json:permissions
Downloads locally with URL.createObjectURL and an <a download> element rather than the privileged downloads API. — chunks/DownloadButton-CTk3AwRh.js:DownloadButton c function
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
No nativeMessaging permission or localhost-specific host is declared. — manifest.json:permissions and host_permissions
Runtime services are remote HTTPS telemetry, billing, and Google APIs; no localhost endpoint appears. — background.js/chunks/api-Cw_K5pGB.js:endpoint review
Does it decode, decrypt, or unpack hidden data and then execute or inject it?
No evidence of this behavior was found in the reviewed package.
Converts base64 to bytes and back solely to store or merge generated PDF data. — background.js:LE/RE and PDF merge functions
Parses PDF function syntax into an internal AST and optional WebAssembly module; no remote extension payload is executed. — pdfjs/pdf.worker.legacy.min.mjs:constructPostScript/buildPostScriptWasmFunction
No telemetry, paywall, license, or Google response reaches a script-execution sink. — background.js:network-to-code review
Can ordinary websites access privileged extension features through messaging or exposed files?
Only pages on *.webtopdf.space are authorized to send external messages, and the sole accepted command stores a license key. Ordinary unrelated websites cannot reach debugger, page-export, storage, or Drive operations.
Restricts external messaging to vendor subdomains and exposes only guide.css with a dynamic URL. — manifest.json:externally_connectable and web_accessible_resources
Rejects every external message except SAVE_LICENSE_KEY and exposes no response data beyond success. — background.js:$E onMessageExternal handler
Powerful PDF/debugger commands are handled on the internal runtime message channel, not the external one. — background.js:rD internal onMessage handler
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Website-specific DOM selectors implement user-visible export modes for supported page types. — content-scripts/print.js:GS mode dispatch
Local trial count and remote license/paywall response determine when the visible payment prompt appears. — chunks/DownloadButton-CTk3AwRh.js:ml paywall flow
No covert date gate, user targeting, or remotely enabled page-access behavior was found. — background.js:behavioral condition review
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
CPU and memory work is tied to printing and merging the requested page. — background.js:HE/UE/VE PDF pipeline
PDF.js work converts a generated PDF to requested downloadable output after user action. — chunks/DownloadButton-CTk3AwRh.js:PDF/image download pipeline
No miner, proof-of-work loop, or unrelated continuous computation was found. — background.js/content-scripts/*.js:background-task review
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Uses the style manager to hide form/action controls during printing without changing their values, action attributes, or listeners. — content-scripts/print.js:DeepSeek and other export handlers
User-selected elements are visually hidden with display:none and can be restored; no form destinations are touched. — content-scripts/RemovalMode.js:element-removal handler
No assignment to form.action, input.value, or submission endpoints appears in first-party export control flow. — content-scripts/SelectionMode.js/content-scripts/print.js:form mutation review