Is Fonts Ninja safe?
We analyzed Fonts Ninja version 9.0.2's actual code and gave it a 68/100 trust score. Fonts Ninja is purpose-aligned but has broad page access and sends…
Bottom line
Fonts Ninja is purpose-aligned but has broad page access and sends detailed font and page information to its service during analysis.
What it can access
It can inspect fonts across all HTTP(S) pages, send analysis data to its service, and capture the visible tab for exports, fitting its purpose but remaining broad. [Q1] [Q2] [Q5] [Q6]
Security weaknesses
Temporary request-header changes are narrowly limited, but heavily minified code makes important behavior harder to independently review. [Q10] [Q18]
Signs of misuse
During user-started analysis it sends page and font details, and sometimes raw font files, to Fonts Ninja for identification; this is sensitive but purpose-related. [Q6] [Q14]
Code findings
What access does this extension ask for, and does that access make sense for what it claims to do?
It requests tabs, activeTab, storage, scripting and access to every HTTP(S) page. Broad page access is necessary to inspect fonts on arbitrary sites, while tabs and capture access also support the user-requested export feature.
Declares activeTab, tabs, storage and scripting, grants all HTTP(S) host access and installs the content script on all HTTP(S) pages. — manifest.json:3
The content controller waits for the fn-activate event before opening the scanner and exposes the explicit capture/export action. — content-scripts/content.js:1091
Which websites can it run on, and can it read or change what appears on those pages?
After activation it reads stylesheets, font-face rules, computed styles, loaded font resources and element geometry to identify the fonts in use. It adds its own shadow-page panel and temporary visual highlighting.
Collects page font sources and usage, analyzes matching elements and mounts the Fonts Ninja interface and highlights. — content-scripts/content.js:8, 1091
Allows the content script to run on all HTTP(S) pages so it can perform the advertised inspection. — manifest.json:3
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
No evidence of this behavior was found in the reviewed package.
The reviewed collectors operate on font resources, styles and rendered font instances rather than input values. — content-scripts/content.js:8, 1091
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
No evidence of this behavior was found in the reviewed package.
Does not declare cookies, history, bookmarks or downloads permissions. — manifest.json:3
Network fetches omit credentials, so font and CSS requests do not deliberately attach browser cookies. — background.js:97
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
The extension can capture the visible tab during its user-requested font-report export. The capture is assembled into a PDF and downloaded locally.
The validated capture-tab message calls tabs.captureVisibleTab only after confirming that the sender is still the visible tab. — background.js:97
The export UI starts capture, creates a PDF blob and downloads it through a temporary object URL. — content-scripts/content.js:1091
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
For a user-initiated analysis it sends the page domain and URL, font hashes, family and format information, source URLs and pairing data to services-v2.fonts.ninja. If a font remains unidentified, it can additionally send up to 20 font files of at most 4 MB each as Base64 with parsed font details.
Builds identify-by-md5, identify-run and identify-genes requests; the fallback attaches sourceBase64 for bounded unidentified font files. — content-scripts/content.js:8
Validates those request types and posts them to the Fonts Ninja API identification endpoints. — background.js:1, 97
Does it download or run code, settings, or instructions supplied by a remote server?
The Fonts Ninja services returns font identities and pairing results, and the panel embeds the vendor's HTTPS website. The extension consumes those responses as structured data or cross-origin web content.
Posts structured font-identification requests to api-v2.fonts.ninja and returns parsed identity data to the content script. — background.js:1, 97
Loads only https://fonts.ninja/ URLs in the nested iframe and validates messages from that iframe by source and exact origin. — chunks/frame-DefUb3bn.js:1
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
No evidence of this behavior was found in the reviewed package.
Handles fn-activate before opening analysis and ties runCaptureSession and promotional navigation to interface callbacks. — content-scripts/content.js:1091
Checks that capture requests originate from the currently visible sender tab. — background.js:97
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.
Declared permissions do not include proxy, search, management or settings-related capabilities. — manifest.json:3
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
The main bundles are heavily minified and include a large third-party font-processing engine, which makes independent review harder. That is suspicious-looking but not evidence of abuse by itself.
A roughly 1.5 MB minified bundle combines the service worker, API client and font parser. — background.js:1-97
A roughly 670 KB minified bundle contains page collection and the user interface. — content-scripts/content.js:1-1091
Does it use eval(), new Function(), or string-based timers to turn text into executable code?
No evidence of this behavior was found in the reviewed package.
The bundled font-processing/runtime code contains the fixed Function('return this')() fallback. — background.js:1
Remote API responses are parsed as identity data and remote font/CSS bytes are handled by packaged parsers, not passed to Function. — background.js:97
Does it track the websites, pages, searches, or links you visit?
No evidence of this behavior was found in the reviewed package.
Constructs page data with location.hostname and location.href split only at #, then includes it in identification requests. — content-scripts/content.js:8
Analysis is started by the fn-activate flow rather than an unconditional background upload on every page visit. — content-scripts/content.js:1091
Does it create a persistent ID or browser fingerprint to recognize you?
No evidence of this behavior was found in the reviewed package.
Stores Fonts Ninja access and refresh tokens after the protected login flow. — background.js:97
Uses local keys for tutorial, theme, icon and promotion counters; no device-fingerprint collector was found. — content-scripts/content.js:1091
Does it send cookies, session details, authentication data, or page contents elsewhere?
It sends the current analyzed URL and detailed font information to Fonts Ninja. For unidentified fonts it may also send the raw font file.
Adds page URL, font metadata, source URLs and optionally sourceBase64 to identification messages. — content-scripts/content.js:8
Posts the validated identification payloads to the vendor and uses credentials: omit for resource fetches. — background.js:97
Does it record typing, form entries, clipboard contents, or screenshots?
A user-requested export captures the visible tab while cycling through identified font examples, then creates and downloads a PDF locally. No keystroke, form-entry or clipboard monitor was found, and no screenshot upload destination was found.
runCaptureSession hides the panel, requests visible-tab images, assembles PDF bytes and passes them to a local download helper. — content-scripts/content.js:1091
capture-tab returns a JPEG data URL only to the requesting content script after a visible-tab check. — background.js:97
Can a website or remote server send commands that make the extension take actions?
No evidence of this behavior was found in the reviewed package.
Returns structured font identity and pairing data from the Fonts Ninja API. — background.js:1, 97
Validates remote iframe source/origin and handles a fixed set of panel message types. — chunks/frame-DefUb3bn.js:1
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Tracks fn-store-counter, fn-store-seen and fn-insta-seen and wires the resulting promotion controls to user interface actions. — content-scripts/content.js:1091
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
To fetch page CSS that rejects extension requests, the service worker can temporarily set the Referer header to the analyzed page origin for the exact CSS request, then removes the session rule. Font and CSS fetches omit credentials and enforce protocol, private-host and size restrictions.
Creates a temporary narrowly scoped declarativeNetRequest rule for a CSS URL, performs the fetch and removes the rule; resource fetches omit credentials. — background.js:1, 97
Declares declarativeNetRequestWithHostAccess to support the scoped request-header adjustment. — manifest.json:3
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
Does not declare nativeMessaging. — manifest.json:3
Validates requested and redirected resource URLs and rejects private/local hosts unless they match the sender page hostname. — background.js:1, 97
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.
Provides bounded Base64 and zlib helpers and parses remote font bytes with packaged code; the reviewed outputs are not passed to an execution sink. — background.js:1, 97
Can ordinary websites access privileged extension features through messaging or exposed files?
No evidence of this behavior was found in the reviewed package.
Rejects messages whose sender ID is not the extension and validates namespaces, operation names and payload schemas. — background.js:1, 97
Requires the parent window and correct nonce, and accepts remote iframe messages only from the iframe window at https://fonts.ninja. — chunks/frame-DefUb3bn.js:1
Exposes frame.html with use_dynamic_url enabled, reducing stable cross-site addressing. — manifest.json:3
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Uses one all-HTTP(S) content-script rule rather than selective domain targeting. — manifest.json:3
Uses the common fn-activate path for page analysis. — content-scripts/content.js:1091
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Caps raw unidentified-font fallback processing at 20 files and 4 MB per file. — content-scripts/content.js:8
Applies request timeouts and size limits to CSS and font fetches. — background.js:1, 97
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Reviewed interaction code mounts a shadow-DOM panel, highlights font examples and manages capture state rather than intercepting or redirecting forms. — content-scripts/content.js:1091