---
title: Website defacement monitoring: would you notice before your customers do?
description: Your uptime check said 200 OK all weekend while the page served spam links. How website defacement works today, and how to catch it within minutes.
canonical: https://watchfor.io/blog/website-defacement-monitoring
---

# Website defacement monitoring: would you notice before your customers do?

2026-10-20 · WatchFor Team · Security · security, web, monitoring

Your uptime check said 200 OK all weekend while the page served spam links. How website defacement works today, and how to catch it within minutes.

Monday, 8:40. An email from a customer, subject line *"Is this you?"*, with a
screenshot attached. It is your home page. The logo is there, the menu is
there, the prices are right. At the bottom, under the footer, there are forty
links to casino sites. Your dashboard shows green for the whole weekend: the
page answered **200 OK** every minute, fast, from every location.

Nothing was down. The page just stopped being yours.

That is what most defacement looks like now. The black screen with "hacked by"
across it still happens, but it is the loud minority. The quiet versions pay
better, so they are built to stay unnoticed for as long as possible, and the
person who finally notices is rarely on your team.

## Why "200 OK" tells you nothing here

An uptime check asks one question: did a working page come back? A defaced
page is a working page. It loads, it is fast, it returns the right status code.
Every check that measures availability, speed or the certificate passes,
because none of those things changed.

To see tampering, a check has to ask a different question: **is this still the
page we published?** That needs something to compare against, and a sense of
which differences matter.

## What tampering looks like in 2026

| What the attacker does | What visitors see | Why it goes unnoticed |
| --- | --- | --- |
| Classic defacement ("hacked by…") | A replaced page or banner | It doesn't, for long. Loud, but rare |
| SEO spam: hidden links injected into templates | Nothing, or a footer full of links | Hidden with CSS; only search engines read it |
| Conditional redirect | Some visitors land on another site | Often only for mobile or search traffic, never for you |
| A new script next to the checkout | Nothing at all | It copies what people type and lets the payment through |
| A trusted vendor script changes its code | Nothing at all | Same address as yesterday, different code |
| A form now posts somewhere else | The same form | Logins or card details go to a third party |
| Security headers removed or loosened | Nothing | It opens the door for the next step |

Card skimmers deserve their own article, and they have one:
[Magecart and injected scripts](/blog/magecart-injected-scripts) covers how
that code gets in and what PCI DSS 4.0 now asks of you. This post is about the
broader question: knowing within minutes when any page that matters changes in
a way you didn't make.

## Compare with a baseline, not with the last check

The obvious approach is to diff each check against the previous one. It fails
in two ways. Every deploy becomes an alert, so people stop reading them. And a
change that slipped through once becomes "normal" at the next check, so the
diff goes quiet while the spam links stay.

WatchFor's [page integrity monitor](/page-integrity-monitoring) compares every
check with a **baseline you accepted**. A change keeps showing until someone on
your team looks at it and either accepts it or fixes it.

It also ignores the churn that makes a plain HTML diff useless. Your own
scripts get new file names on every build, so they never count as a *new
source*. What it looks at is what an attacker changes:

- **Script sources.** A page loads JavaScript from a host that isn't your
  site, isn't in the baseline and isn't on your trusted list.
- **Script code.** A third-party script keeps its address but serves different
  code. The same check on your own scripts is a warning, because that is
  usually your deploy.
- **Forms.** A form now submits to another site.
- **Redirects.** The page now ends up on a different host.
- **Tamper words.** "Hacked by", "defaced by", or any words you add yourself.
- **Security headers.** Content-Security-Policy, HSTS, X-Frame-Options or
  X-Content-Type-Options removed, HSTS shortened, or a CSP that now allows
  inline or any-host scripts.
- **Visible text.** The page's words differ from the baseline by more than the
  sensitivity you chose.
- **External links and frames.** Five or more new link domains (the SEO-spam
  pattern), or a new iframe from another host.

![A page integrity monitor's findings: a new external link on the home page, three new external links on /newest, and text changes of 65% and 60%, each measured against the accepted baseline](/blog/website-defacement-monitoring-findings.webp)

Each finding is its own alert rule, so one event opens one incident with a
root cause in plain words: which page, what changed, and the host involved.

## Setting it up for the pages that matter

1. **Create a Page integrity monitor** and enter your site's address. The home
   page is added for you. Add the pages an attacker would pick: login, sign-up,
   checkout, pricing. **Import from sitemap** fills the list in one go.
2. **Choose a sensitivity** for text changes: Low (50%), Normal (25%) or High
   (10%). A busy blog index can be relaxed while the checkout stays strict;
   each page can have its own value. New scripts, rewired forms, redirects and
   tamper words alert at any sensitivity.
3. **Tell it what changes on its own.** Up to 20 CSS selectors, such as a
   cookie banner or live prices, are left out of the text and link comparison.
   Scripts are always checked: a selector can never hide one.
4. **Leave the first check alone.** It records the baseline for every page.
   From the next check on, each page is compared with it.

When something changes, open the page to see exactly what: the word diff, the
scripts, forms, frames and headers, each marked new or changed.

![One watched page opened: the summary shows text 65% changed, security headers unchanged, one known script source and one known form, with baseline and current screenshots side by side and an Accept as new baseline button](/blog/website-defacement-monitoring-change.webp)

On Pro and above, **browser mode** renders each page in a real Chrome. That
catches what only exists after the page runs: a script added by another
script, a tag manager loading a new vendor, a page that starts sending data to
a host it never talked to before. It also keeps a screenshot of the baseline
and of any check that found a difference, so you can see *Baseline | Now* side
by side.

## Your own deploys shouldn't page you

The fastest way to make an integrity monitor useless is to let it alert on
every release. So make accepting your changes part of the release:

```bash
curl -s -X POST "https://watchfor.io/api/v1/monitors/<monitor-id>/baseline?fresh=true" \
  -H "Authorization: Bearer wf_live_YOUR_WRITE_KEY"
```

Run it as the last step of the deploy. `fresh=true` checks the pages first and
accepts what that check saw, never the version from before the release.

There is also a built-in grace period. A finding alerts only when a second
check confirms it, about five minutes after the first sighting. If your
pipeline accepts the new baseline within those minutes, the confirming check
compares against the new version and finds nothing, so the release never
pages anyone. No maintenance window needed.

![The alert rules of a page integrity monitor: unknown script source, form sends data elsewhere, tamper keywords, redirects elsewhere, security header weakened, third-party script changed, page content changed, security headers changed and first-party script changed](/blog/website-defacement-monitoring-rules.webp)

For changes nobody gets round to reviewing, such as a marketing edit on a
Friday, you can let unreviewed changes become the baseline after 1 to 24 hours.
Security findings (new scripts, changed code, forms, headers, redirects, tamper
words) still wait for a person unless you explicitly include them. An attacker
can wait 24 hours too.

## Two details that matter on a bad day

**One clean check doesn't close it.** Tampering is sometimes served only to
some visitors. A security finding stays open until three checks in a row come
back clean, so one lucky check from another location can't quietly resolve an
incident while the skimmer is still there.

**It doesn't go on your status page.** Integrity incidents are never published
to a public status page automatically. Tampering isn't downtime, and the
details could show attacker hosts to the world. If you want to tell customers,
someone on your team publishes it on purpose.

## What it won't catch

Being honest about the edges is part of trusting the alerts:

- **Pages you don't watch.** The monitor compares the pages on its list. Put
  the ones that take logins, money or personal data on it first.
- **Pages behind a login.** It sees what a logged-out visitor sees. An account
  area or an admin panel is out of its reach.
- **Tampering aimed narrowly.** Content shown only to visitors from one country
  or one referrer may not reach our locations on a given check. The more pages
  and the shorter the interval, the smaller that gap, but it is a gap.
- **A breach that changes nothing visible.** A stolen database or a backdoor on
  the server with no change to the pages is a job for server-side security, not
  for an outside check.

It is a smoke detector, not a firewall. It won't stop the attack, but it turns
"a customer emailed us a screenshot on Monday" into "we were paged on Saturday
at 3:07, five minutes after it happened."

## Start with three pages

You don't need to watch the whole site on day one. Home, login and checkout
cover most of what attackers go for. Create a
[page integrity monitor](/page-integrity-monitoring), let the first check
record the baseline, and add the deploy hook to your pipeline so your own
releases stay quiet. Page integrity starts on the Starter plan; the
[pricing page](/pricing) has the details.

If you want to see what a page looks like to the rest of the internet right
now, the free [Smart Website Checker](/smart-website-audit) and
[Security Headers Checker](/security-headers-checker) are a good first look.

---

Canonical page: https://watchfor.io/blog/website-defacement-monitoring · All articles: https://watchfor.io/blog/all.md · Site guide: https://watchfor.io/llms.txt
