Is SEO Pro Extension safe?
We analyzed SEO Pro Extension version 2.5's actual code and gave it a 65/100 trust score. This is a useful but broadly empowered SEO tool with a notable…
Bottom line
This is a useful but broadly empowered SEO tool with a notable exposed-interface weakness and limited URL sharing.
What it can access
It reads visible content across nearly every website and monitors navigation, which is broader than a user-selected SEO check.[Q1][Q2][Q4][Q6]
Security weaknesses
The exposed popup and unsafe webpage-data rendering could let a malicious page interfere with the extension interface.[Q11][Q21]
Signs of misuse
It shares full inspected URLs with Google and opens company pages during installation or updates, but no page-content theft or remote control is established.[Q6][Q8]
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 HTTP and HTTPS page plus webRequest and webNavigation. That broad reach supports an SEO inspector, but it exposes all visible page content and navigation URLs rather than limiting access to the page the user explicitly asks to inspect.
Runs a content script on all HTTP/HTTPS pages, grants the same broad host access, and requests webRequest and webNavigation. — manifest.json:22-34
Collects headings, links, images, JSON-LD and microdata, page metadata, social fields, the complete URL, and all visible body text. — js/inject.js:1-202
Observes completed top-level navigations and keeps their URLs and HTTP status codes in a per-tab memory map. — background.js:197-245
Which websites can it run on, and can it read or change what appears on those pages?
It runs on every ordinary website and can read nearly all visible page text and SEO-relevant structure. Its only direct page change is a user-triggered visual highlight on nofollow links.
The content script and host permissions cover http://*/* and https://*/*. — manifest.json:22-30
Reads visible body text, headings, links, images, metadata, and structured data from each matched page. — js/inject.js:1-202
Can add or remove a CSS class on nofollow links after the popup button is clicked; it does not change their destinations. — js/inject.js:205-227
Can it see sensitive information you type, such as passwords, payment details, messages, or form entries?
It does not read input, textarea, select, password, or payment-field values. It does read the entire visible body text, so sensitive information already rendered as ordinary text—such as messages or account details—can be included in its local page analysis.
Reads document.body.innerText/textContent and includes it in the SEO result, but has no form-control value reads. — js/inject.js:125-169
Reads anchor text and image metadata, not input or form fields. — js/inject.js:14-24
Can it access private browser data such as cookies, signed-in sessions, browsing history, bookmarks, or downloads?
It observes top-level page URLs and response codes while installed and holds the current navigation chain in memory by tab. It does not request cookies, saved browser history, bookmarks, downloads, or session-store access, and the observed URLs are not persisted.
webNavigation and webRequest handlers maintain main-frame URLs and status codes in an in-memory Map keyed by tab ID. — background.js:197-245
Declares webRequest and webNavigation but no cookies, history, bookmarks, downloads, or storage permission. — manifest.json:28-34
Can it access anything else on your device, such as files, location, camera, microphone, clipboard, or installed applications?
No evidence of this behavior was found in the reviewed package.
Does it send information outside your browser? If so, what information is sent, where does it go, and why?
When the popup opens, it sends the complete active-page URL—including path and query parameters—to Google's Chrome UX Report services for performance metrics. Install, update, and uninstall events also contact fixed MarketingSyrup pages; no extracted body text, headings, cookies, or form values are uploaded by the extension's own request code.
Popup initialization sends SEO.url to the background as the website for the Web Vitals request. — js/popup.js:252-270
POSTs the supplied full URL to chromeuxreport.googleapis.com; on failure it retries with the same full value under the origin field. — background.js:27-67
Opens fixed MarketingSyrup pages on install/update and registers a fixed uninstall URL. — background.js:1-25
Does it download or run code, settings, or instructions supplied by a remote server?
No evidence of this behavior was found in the reviewed package.
Parses the Google response as JSON and extracts three numeric performance metrics. — background.js:27-85
Background and content-script entry points name packaged JavaScript files. — manifest.json:15-26
Can it take actions without a clear user request, such as opening pages, redirecting searches, downloading files, or sending requests?
Install and update automatically open MarketingSyrup pages. More importantly, every completed navigation and active-tab change asks the page access to run its full page extractor just to calculate two icon flags; the returned result is narrowed locally and is not uploaded.
Creates an active MarketingSyrup tab automatically after installation or update. — background.js:1-21
Tab activation and top-level navigation call setIconAndBadge, which sends Update icon to the page. — background.js:115-183,197-210
The Update icon action calls the same complete getSeoData extractor, then returns only canonical/noindex booleans. — js/inject.js:240-259
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.
Is any important behavior difficult to inspect because the code is hidden, heavily obfuscated, dynamically generated, or supplied by third parties?
No evidence of this behavior was found in the reviewed package.
Complete service-worker behavior is plain, formatted JavaScript. — background.js:1-246
Complete page-side behavior is plain, formatted JavaScript. — js/inject.js:1-260
Standard minified jQuery 3.5.1 bundle used by the popup. — js/jquery.min.js:1-2
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 standard library includes globalEval and script-element insertion helpers; no application code calls globalEval or jQuery AJAX script loading directly. — js/jquery.min.js:2
Manifest V3 package declares no relaxed extension-page content security policy. — manifest.json:1-40
Application code does pass page-controlled strings into HTML-rendering methods, enabling non-script markup injection. — js/popup.js:297-338,385-405,535-683
Does it track the websites, pages, searches, or links you visit?
No evidence of this behavior was found in the reviewed package.
Stores main-frame URLs and response codes in statusInfo, resetting the per-tab list after navigation completion. — background.js:197-245
Returns the in-memory status chain to the popup; no external upload path uses statusInfo. — background.js:89-112
Does it create a persistent ID or browser fingerprint to recognize you?
No evidence of this behavior was found in the reviewed package.
statusInfo Map is keyed by tab ID (ephemeral) and reset on navigation; no persistent ID is generated or stored. — background.js:197-211
No storage permission is declared; no chrome.storage or IndexedDB usage appears in any mapped file. — manifest.json:1-40
Does it send cookies, session details, authentication data, or page contents elsewhere?
It does not read cookies, session stores, authorization headers, or form fields, and it does not upload extracted page contents. It does send the full active-page URL to Google, so credentials, private identifiers, searches, or other sensitive values embedded in a URL could be disclosed.
Passes the complete SEO.url value to the Web Vitals request. — js/popup.js:252-259
Serializes that full value into the Google request body without removing paths, fragments, or query parameters. — background.js:41-56
Does not request cookies or another session-data permission. — manifest.json:32-35
Does it record typing, form entries, clipboard contents, or screenshots?
No evidence of this behavior was found in the reviewed package.
All functions perform DOM reads (querySelector, textContent) or CSS class toggling; no addEventListener for keydown, input, or clipboard events. — js/inject.js:1-260
No clipboardRead, tabs, or debugger permission is declared. — manifest.json:1-40
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.
Reads page-controlled text, metadata, links, images, and schema and returns them to the popup. — js/inject.js:1-202,240-259
Uses .html() and HTML-template .append() calls with those unescaped values. — js/popup.js:297-338,385-405,535-683
Runtime message handler has no remote instruction or arbitrary-action mechanism. — background.js:91-112
Does it alter links, referral codes, advertisements, shopping carts, or search results?
No evidence of this behavior was found in the reviewed package.
Highlight Nofollow Links toggles the nofollow_highlighted CSS class on existing anchors; it does not change href, rel, or any other attribute. — js/inject.js:205-228
Does it redirect or modify web traffic, request headers, downloads, or proxy settings?
No evidence of this behavior was found in the reviewed package.
Read-only onHeadersReceived listener copies URL and statusCode into memory and returns no modified request. — background.js:222-245
Declares webRequest and webNavigation but no declarativeNetRequest, downloads, or proxy permission. — manifest.json:32-35
Can it communicate with software on the computer or services running on localhost?
No evidence of this behavior was found in the reviewed package.
The sole fetch calls target chromeuxreport.googleapis.com; no 127.0.0.1, localhost, or native-messaging port is referenced. — background.js:27-63
No nativeMessaging permission is declared. — manifest.json:1-40
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.
All functions are straightforward DOM queries and message handlers; no atob, eval, new Function, or dynamic script injection. — js/inject.js:1-260
Service worker contains only lifecycle handlers, message routing, and a fetch to Google; no decode-and-execute pattern. — background.js:1-250
Can ordinary websites access privileged extension features through messaging or exposed files?
The popup is unnecessarily exposed as a web-accessible resource on every site, so an ordinary webpage can load or frame the extension page. The parent page cannot directly read the cross-origin popup result, but it can present or clickjack its controls; combined with raw page-data rendering, the exposed popup increases the practical UI-injection surface.
Exposes popup.html to <all_urls> even though toolbar popups do not need web-accessible-resource status. — manifest.json:36-39
On load, the popup queries the active tab, requests its SEO data, and installs export and page-highlight controls. — js/popup.js:27-164
Renders attacker-controlled page fields into the extension page as HTML rather than text. — js/popup.js:297-338,385-405,535-683
Does suspicious behavior activate only for certain users, websites, dates, or remote settings?
No evidence of this behavior was found in the reviewed package.
Content script matches http://*/* and https://*/* with no per-site exclusions or inclusions. — manifest.json:18-24
No Date checks, user-agent parsing, A/B flags, or remote-config fetches gate any behavior. — background.js:1-250
Does it perform hidden resource-intensive work, such as cryptocurrency mining?
No evidence of this behavior was found in the reviewed package.
Service worker contains only event listeners, a fetch, and UI badge updates; no Worker, SharedArrayBuffer, or intensive loop. — background.js:1-250
Popup logic is DOM rendering and messaging; no compute-heavy or hidden background task. — js/popup.js:1-500
Does it change form fields or where a form sends its information?
No evidence of this behavior was found in the reviewed package.
Extraction contains no input.value, form.action, FormData, submit listener, or form-control query. — js/inject.js:1-202
The only page mutation is adding or removing a visual CSS class from existing nofollow anchors. — js/inject.js:205-227