A monitoring script served from a DebugBear URL sold positions and moved funds out of some Polymarket users' wallets, and it never needed their passwords. It worked because the code ran with the access of visitors who were already signed in. Could you list every script that loads on your own logged-in pages?
This guide treats the incident as the trigger. The method works for any third-party script, and it ends with a checklist you can hand to developers and security staff.
What the DebugBear incident reports
Per Search Engine Journal's report, DebugBear told customers on October 29 to remove its Real User Monitoring script after a security incident. The company said attackers compromised its DNS records through its domain registrar. Its initial investigation pointed to an attack on one customer's website, and it reported no sign that its internal systems were breached.
Hudson Rock found malicious JavaScript at a DebugBear script URL that Polymarket used. According to the report, the code looked for the trading client already present in a logged-in browser. Polymarket's October 30 incident report confirmed that positions were sold and funds moved from some users' wallets, without needing anyone's password.
Search Engine Journal says it is not yet clear whether other DebugBear customers received malicious code. Treat that as unknown, not as reassurance.
The lesson for your audit is mechanical. A script included on a page runs with the permissions of whoever is viewing it, so a signed-in visitor's access becomes the script's access.
Step 1: Build the inventory
You need one list that combines four sources, because no single view shows everything.
Capture what the browser actually loads
Open Chrome DevTools, go to the Network tab, tick "Disable cache" and reload. Filter to third-party requests or sort by domain, and check the Initiator column to see what pulled each script in.
Repeat this on a home page, an article or product page, a login page, an account page and a checkout page. Do it both signed out and signed in.
Compare view-source with the rendered page. A script that appears only in the rendered DOM was injected by something else, usually a tag manager or another script.
Read the tag manager
List every tag, trigger and custom HTML tag in the container. Note who published the last version and when. Custom HTML tags deserve extra attention, because they can load anything.
Search templates and plugins
Ask a developer to search theme files, header and footer partials, and plugin settings for external script URLs. Check CMS fields where editors can paste code. If you run a rendering crawler, extract external script sources site-wide to catch pages that differ from your samples. This pairs well with noindex vs robots.txt for shared pages: how to audit explained.
Record it in a template
Use these columns. Give every script a row, including the ones nobody remembers adding.
| Script / URL | Source (template, plugin, tag manager, hardcoded) | Owner | Pages loaded on | Loads when signed in? | Privilege level | Business need | Action | |---|---|---|---|---|---|---|---| | | | | | | | | Remove / Keep / Isolate |
An empty owner cell is a finding. A script with no owner and no stated business need is a removal candidate.
Step 2: Classify each script by privilege
Privilege here means what the script could do if it turned hostile. Rank it with two questions: does it load on pages where a visitor has a session, and can it load other code?
- High: loads on logged-in, account, checkout or admin pages, or is a tag manager or loader that can pull in other scripts.
- Medium: loads on public pages that signed-in users also visit, but not on account or payment screens.
- Low: loads only on pages with no sessions, such as a static marketing site on a separate domain.
A RUM script usually loads site-wide, so it can reach account pages too. That is the exposure the DebugBear case illustrates.
Step 3: Decide remove, keep or isolate
Remove anything with no owner, no current business need, or a duplicate function. Keep scripts with a clear owner and need, but cut their reach. Isolate means limiting where a script loads so it never runs on sensitive pages.
For monitoring tools, one practical option is to exclude authenticated and checkout paths in the tag manager trigger. You lose some field data on those pages, so confirm the tradeoff with your performance owner. Where a vendor offers a sandboxed iframe or server-side option, ask the developers whether it fits.
Illustrative walkthrough: a hypothetical store
This example is invented to show the process. The site, scripts and decisions are not real data.
Imagine a small online store with a blog, product pages, customer accounts and checkout. The inventory turns up these scripts.
| Script | Source | Loads on | Signed-in? | Privilege | Decision | |---|---|---|---|---|---| | Tag manager container | Theme header | All pages | Yes | High | Keep, restrict publishing rights, review version history | | RUM performance script | Tag manager | All pages | Yes | High | Remove from account and checkout triggers; confirm need elsewhere | | Web analytics | Tag manager | All pages | Yes | Medium | Keep, owner is marketing | | Live chat widget | Plugin | All pages | Yes | High | Isolate to support and help pages | | Heatmap tool | Old theme file | Product pages | Sometimes | Medium | Remove, no owner, trial ended | | Review widget | Template | Product pages | No | Low | Keep |
The heatmap script is the useful surprise. Nobody on the team added it recently, and it was hardcoded in a template, so a tag manager review alone would have missed it. The RUM script is the reverse case. It was easy to find, but its trigger covered checkout, which nobody intended.
The outcome: one removal, two scope reductions (RUM and chat) and one tag manager tightening.
Step 4: Verify the removal
A deleted tag only matters if browsers stop loading it. Run these checks.
- Open a fresh private window with no extensions, load each sampled page type, and confirm the script domain no longer appears in the Network tab.
- Repeat after purging the CMS cache, CDN and any full-page cache. Cached HTML can keep serving the old embed.
- Search the rendered HTML and the source for the script URL and script ID.
- Check the tag manager's version history. Confirm the removal is published, note who published each recent version, and flag any change nobody can explain.
- If you run Content-Security-Policy, review violation reports. A Report-Only policy that lists allowed script sources will surface unexpected domains without breaking pages. Ask developers to set one up if none exists.
- Retest signed in, since logged-in templates sometimes differ.
What verification cannot tell you
These checks confirm a script stopped loading. They say nothing about what it did before. As Search Engine Journal reports, removing a tag prevents new loads but does not reverse unauthorized actions or remove anything an attacker may have planted.
Subresource Integrity is not a fix for every case. It pins a script to a known hash, which works for static files you host. It breaks vendor scripts that change often, because every update changes the hash.
In the DebugBear case, the reported problem was malicious content served from a legitimate script URL. A hash on a frequently changing vendor file would likely have meant constant maintenance. That is an inference; Search Engine Journal does not state it.
An SEO also cannot judge compromise alone. Log review, session handling and backdoor hunting belong to developers and security staff.
Escalation checklist for dev and security teams
Hand over the inventory and these requests. Items 1 through 6 mirror the actions Search Engine Journal recommends for DebugBear users. Item 7 is an addition.
- Sessions: invalidate sessions for administrators and privileged users who loaded affected pages, and confirm old sessions are rejected, since a password change may not end them.
- Credentials: reset passwords and revoke API keys that may have been exposed. If exposure cannot be scoped, widen the reset.
- Tag manager history: compare versions against a known clean one, and review who has publish access.
- Logs: look for unusual logins, new accounts, permission changes, changed files and unexpected transactions during the period the script was active.
- Persistence: check templates, plugins and injected scripts for backdoors against a clean version.
- Containment: if you confirm a compromise, serve a static maintenance page with an HTTP 503 until the site is cleaned or restored.
- Vendor contact: ask any affected vendor for indicators and a timeline. Search Engine Journal reports that DebugBear said it could not receive email at its domain and pointed customers to its X account.
What to expect next
The DebugBear story is still developing, and Search Engine Journal's report does not say whether other customers were served malicious code. Expect vendor updates and security write-ups to refine the picture.
In the meantime, repeat the audit each quarter and whenever someone adds a tag. That keeps the inventory current and gives every script a named owner.



