Bookmarklet Security

What a javascript: bookmark can access, which browser controls still apply, and how to review code before it touches a real page.

A bookmarklet is code, not a special safe bookmark

Clicking a bookmarklet asks the browser to run JavaScript in the current page. If you would not paste the same code into that page's developer console, do not run it as a bookmarklet. A recognizable name, short length, minification, or a successful sandbox test is not a safety guarantee.

Page access

Code can read and change the current page's DOM and may access JavaScript-readable cookies and storage associated with that page's origin.

Browser limits

HttpOnly cookies remain unavailable. Same-origin rules, CORS, permissions, popup rules, and Content Security Policy can block operations; behavior varies by browser and page.

Network risk

A request can transmit data even when CORS prevents the code from reading the response. The destination and outgoing payload matter more than whether a response succeeds.

The browser security model in plain language

A bookmarklet normally runs as script associated with the page you are viewing. That gives it useful DOM access: it can count links, restyle text, read visible content, fill fields, or remove elements. The same access becomes dangerous when the page contains account details, private messages, customer records, draft text, payment data, or other sensitive information.

The page's origin still matters. JavaScript cannot read HttpOnly cookies, and it cannot freely read arbitrary cross-origin responses. Those protections do not prevent every disclosure. Code can place page data in an outgoing request, image URL, form, query string, WebSocket message, clipboard write, or a new page.

Content Security Policy is not something a bookmarklet can simply “bypass.” A strict policy may block the javascript:execution itself, inline evaluation, external scripts, or network destinations. Browser UI also restricts clipboard, popups, downloads, camera, microphone, and other capabilities. A tool that works on one page may fail on another for legitimate security reasons.

Five-step source review

  1. 1. Decode the complete source

    A javascript: URL is often percent-encoded, which is normal. Decode it into readable JavaScript and make sure there is no second hidden payload in Base64, hexadecimal escapes, character codes, or a downloaded script.

  2. 2. Find every destination

    Search for fetch, XMLHttpRequest, sendBeacon, WebSocket, script src, window.open, and location changes. Record each hostname and the data placed in the URL, headers, request body, or new page.

  3. 3. Trace private page data

    Follow document.cookie, localStorage, sessionStorage, form values, selected text, page content, and clipboard data. A legitimate helper should have a narrow reason for every value it reads.

  4. 4. Review HTML and dynamic code

    Treat eval, new Function, document.write, innerHTML, and insertAdjacentHTML as high-attention areas. Prefer direct JavaScript and textContent or explicit element creation for untrusted page text.

  5. 5. Test away from real accounts

    Use a disposable local fixture first. Do not test unknown code on email, banking, admin, health, customer, payment, or any other signed-in page containing private information.

Examples: capability is not intent

A network request

fetch('https://api.example.com/save', {
  method: 'POST',
  body: selectedText
})

This may be the entire purpose of a “save to service” tool, or it may disclose text. Review the owner of the hostname, the exact payload, authentication behavior, and the service's privacy terms.

A local visual change

document.querySelectorAll('a').forEach((link) => {
  link.style.outline = '2px solid blue';
});

This code is readable and only changes link styles in the current document. You should still verify the complete source, because a short visible excerpt does not prove nothing else runs.

Minification and obfuscation differ

Minification removes whitespace and shortens syntax to fit a URL; the original source should still be available. Obfuscation is intended to make behavior difficult to understand. Do not run a bookmarklet when its author will not provide readable source that corresponds to the installed URL.

Testing has limits

The local fixture restricts request APIs and external resources and does not share your real page origin, which makes it useful for DOM experiments with code you understand. It is not a hostile- code sandbox, cannot reproduce every site's structure or policy, and a script can still replace its own preview. Testing is a supplement to source review, not a replacement.