Mozilla's guidance for building a secure Firefox extension boils down to a short list: bundle your code, insert content safely, keep the default policy, handle page objects with care and keep libraries current. Break these rules and your extension may be rejected on addons.mozilla.org or blocked in Firefox.
The checklist
1. No remote code. Bundle a copy of any script you need. Mozilla says this keeps the code from changing without your knowledge.
2. Insert content safely. Use native DOM methods such as createElement, setAttribute and textContent. If you need HTML, sanitize it with DOMPurify. Mozilla notes that DOMPurify 2.0.6 and older have a cross-site scripting vulnerability, so use a current version. Escape HTML in templating engines.
3. Keep the standard content security policy. Changing it is discouraged. A modified policy that allows remote script injection will fail review.
4. Handle page objects carefully. A malicious page can modify the functions of objects a content script reaches through wrappedJSObject. Be careful with window.eval in content scripts, because a page can exploit it to run its own code.
5. Build UI with extension components. Use bundled pages, page actions and popups. Do not add buttons or toolbars directly into web pages. If you need custom UI in a page, use iframes with data URLs, or extension-hosted iframes that pages cannot interact with.
6. Do not leak internal URLs. Do not inject moz-extension paths directly into pages. Tracking scripts could use the internal UUID to fingerprint users. If you must, embed the paths in an iframe using a data URL or srcdoc.
7. Handle analytics carefully. Mozilla says not to insert the Google Analytics script. Send events to the REST API with an XHR request. More broadly, collect only what you need. The add-on policies require limiting data transmission to what the functionality requires.
8. Keep third-party libraries fresh and unmodified. AMO may disable extensions that contain outdated or altered libraries.
9. Lint for unsafe sinks. Mozilla suggests the eslint-plugin-no-unsanitized plugin to flag unsanitized input.
How to use this list
Turn each item into a check. Items 1 to 3 can run in CI by scanning the built package. Items 2 and 9 belong in your linter. Item 8 is a dependency problem, so scan lockfiles on every build.
What many teams miss
Page-to-extension messaging gets less attention than manifest permissions. Anything a page can send is untrusted input, so validate it. Our content script guide covers the boundary in Chrome, and the same discipline applies in Firefox.
Common mistakes
The most common slip is using innerHTML for convenience with text that came from a server. The second is copying a library into the project and editing it. Both are easy to catch in review if you add them to a pull request checklist and run the lint rule in CI.
Quick check
Can I load a script from a CDN in my Firefox add-on?
Not for execution. Mozilla's guidance says to bundle a copy so the code cannot change without your knowledge.
Is it fine to tweak the extension content security policy?
Mozilla discourages it, and a policy that allows remote script injection fails review.
Sources
Last reviewed: 19 October 2026.