NEGATIVE SEO LINKS
initialising
module

Title

Saved
Traceaudit assistant · online
Trace answers from our documentation. It can't see your site until you run a scan.
CLUSTER LOAD
redis audit_q7 queued
render p5038.4 s
chromium pool24 / 32
WORKER GRID · PROXMOX
ct‑1101 → ct‑116421 active
INGEST STREAM
DETECTIONS · 24H
61 injections found
Live · 1,284 domains audited in the last 24h · 61 with active injections

Someone else is editing your page. Only Google sees it.

We render your URL twice at the same instant — once as a visitor, once as Googlebot — then compares every node, style and coordinate. Injected links, cloaked text and off-canvas anchors surface in about 40 seconds. No account for your first scan.

https://
· 2 full renders per scan · Avg. runtime 38s · disavow.txt generated · Nothing stored without consent
184kpages rendered
2,481nodes per audit
11%domains cloaked
38smedian runtime
dom.stream·ct‑11472 anomalies
2,481 nodes parsed31 toxic outbound
scanning example.com · worker ct‑1147 · proxmox/eu‑west‑3
queue
render
cloaking
css forensics
link graph
score
elapsed 0.0s · streaming over websocket
01 / report

The diagnosis, before the invoice.

Every scan ends in the same place: a scored, evidence-backed picture of what is attached to your domain. Numbers below are a real audit of a compromised WordPress site.

report #A7C‑2291·medi‑supplies.example·38.4s CRITICAL — action required

risk score

0/100
up from 31 last week

hidden anchors

0
23 opacity:0 · 8 off‑canvas

render similarity

0%
visitor vs Googlebot text

clean links

0
of 47 outbound hosts

Where the risk comes from

weighted contribution to the 78-point score
Spam link injection
92
Cloaked content
74
CSS obfuscation
68
Redirect chains
41
Anchor over‑optimisation
29
Core Web Vitals drag
12

Risk trajectory

daily score, last 30 days — injection began on day 19
footer widget compromised
02 / cloaking

Drag the line. Meet the page Google was served.

Two headless browsers hit the same URL in the same second with different identities. If the text diverges, the divergence is the evidence.

Visitor render — Chrome/129 · macOS · 1,212 words
Googlebot render — Googlebot/2.1 · 1,624 words
Sterile packaging for clinical supply chains

We manufacture ISO 11607 compliant pouches and reels for hospital sterilisation departments across the EU. Every batch is traceable to the extrusion lot, and our validation files ship with the order.

Order lead time is eleven working days. Our Lyon facility holds ISO 13485 certification, audited annually by BSI.

Sterile packaging for clinical supply chains — cheap meds, casino bonus, no prescription

We manufacture ISO 11607 compliant pouches and reels for hospital sterilisation departments across the EU. Every batch is traceable to the extrusion lot, and our validation files ship with the order.

◂▸
Jaccard text similarity 71.4% · threshold for a cloaking flag is 92% · injection served only when the request UA matches a crawler signature
03 / css forensics

Links that exist, positioned where no human will ever look.

For every anchor on the page we read the computed style and the real layout box. An element at x:‑9999px with opacity:0 is not a design choice.

medi-supplies.example — layout boxes, 1440×900
off-canvas · x < 0
Reveal hidden nodes
23 anchors · opacity:0 or font-size:0
8 anchors · absolute, x < ‑2000px
412 anchors · visible and accounted for

All 31 hidden anchors resolve to four hosts on the same /24 subnet, injected through a stale footer widget. Hover a marker to read the destination.

04 / coverage

Four passes, one render budget.

Each module reads from the same fully executed DOM, so JavaScript-injected sabotage is caught with the rest of it.

module.injection

Spam link injection

Resolves every outbound host against a live spam-network graph — pharma, gambling, essay mills, CN and ID link farms — then traces the DOM path back to the file that inserted it.

31 / 47 hosts flagged
vector: footer‑widget.js:2
module.cloaking

Crawler cloaking

Simultaneous dual render under a visitor and a Googlebot user-agent, compared on text, metadata, canonical tags and structured data. Reverse DNS confirms the impersonation is server-side.

similarity 71.4% · flagged
412 crawler‑only words
module.layout

CSS obfuscation

getBoundingClientRect plus computed styles for every anchor: zero opacity, clipped rects, negative margins, text-indent tricks, 1px containers and collapsed line-heights.

2,481 boxes measured
31 outside human reach
module.remediation

Disavow & evidence

Exports a Search Console-ready disavow.txt, a timestamped evidence bundle with screenshots and DOM snapshots, and the exact selectors your developer needs to strip.

disavow.txt · 4 domains
evidence bundle 2.1 MB
05 / infrastructure

What happens in those 38 seconds.

Requests queue in Redis so a traffic burst never touches worker memory. Each scan gets a disposable container, and the log you watch is the worker's own stdout, streamed over a socket.

client URL redis audit_q LXC ephemeral render A chrome UA render B googlebot UA websocket live log
IngestBursts absorbed by Redis, never by RAM. Position in queue is shown to the user.
IsolateOne disposable LXC container per audit. Destroyed on completion, nothing persists.
Executeasync_playwright drives real Chromium. JavaScript runs exactly as it would for a visitor.
CompareBoth renders diffed on text, metadata and layout geometry in the same process.
StreamWorker stdout pushed to the browser over WebSocket, line by line, as it happens.
0k
pages rendered to date
0s
median scan runtime
0%
of scanned domains show cloaking
0
scans retained without consent
06 / remediation

You can see the damage for free. Fixing it is the paid part.

Risk score, cloaking verdict and hidden-anchor count are always open. The evidence bundle and the file you hand to Google are not.

domain: pharm-relay-84.top anchors: 12 first seen: 2026‑08‑12 dofollow: yes
domain: casino-tw9.xyz anchors: 7 first seen: 2026‑08‑12 dofollow: yes
domain: rx-overnight-shop.click anchors: 9 first seen: 2026‑08‑13 dofollow: yes
domain: essay-pro-uk.online anchors: 3 first seen: 2026‑08‑14 dofollow: no
selector: footer > div.widget_text > div > a[style*="opacity:0"]
injection file: /wp-content/themes/medi/js/footer-widget.js:2 (base64 payload)
recommended: strip payload, rotate FTP credentials, submit disavow.txt, request review

Full evidence bundle · disavow.txt · fix instructions

31 hidden anchors across 4 domains, with screenshots, DOM snapshots and the exact selector to remove.

07 / plans

Pay for the scan, or for never having to remember to run one.

probe
Free
One-off look at a single URL. No account.
  • Risk score and cloaking verdict
  • Hidden anchor count
  • Live scan console
  • Domain list and evidence
  • disavow.txt export
forensics
€29/ report
The complete audit for one domain, delivered on the spot.
  • Everything in Probe
  • Full toxic domain list with anchors
  • disavow.txt, ready to upload
  • Evidence bundle with screenshots
  • Injection vector and selectors
sentry
€89/ month
Daily re-scans across your properties, with alerts.
  • Up to 25 domains, scanned daily
  • Alerts on score change or new injection
  • 30-day history and diffs
  • Slack and webhook delivery
  • API access, 500 scans/month
nsl / detection

Everything we look for, and how we prove it.

Negative SEO Links runs four detection modules against a single fully executed render. Each one produces evidence rather than a warning: a selector, a coordinate, a diff or a host. This page documents every signal, including the ones we deliberately do not raise.

18signals evaluated
2identities per scan
2,481boxes measured
0.4%false positive rate
the four modules

One render, four passes over it.

Running the browser is the expensive part, so every module reads from the same finished DOM instead of fetching the page again. Open any module for its method and its output.

Spam link injection+
Every anchor is resolved to its destination host and checked against a link graph we rebuild nightly from 2.4 million flagged domains. When a toxic anchor is found we walk the DOM back to the node that created it; if the element was inserted at runtime, we attribute it to the script and line that ran the insertion.
  • Pharmaceutical, gambling, essay-mill and adult networks
  • Subnet clustering — four hosts on one /24 is a campaign, not coincidence
  • Anchor text profiling against your own historical distribution
  • Output: host list, anchor counts, first-seen dates, injection vector
Crawler cloaking+
Two headless Chromium instances request the same URL within the same second under different identities, both executing JavaScript to completion. We compare visible text with Jaccard similarity, plus title, meta description, canonical tag, JSON-LD and the outbound link set.
  • Flag threshold is 92% similarity; healthy sites sit at 96–100%
  • Redirect chains followed under both identities, hop by hop
  • Reverse DNS confirms whether the swap is server-side or client-side
  • Output: word-level diff, similarity score, crawler-only content
CSS obfuscation+
Hiding a link is a layout problem, not a markup problem, which is why source-code scanners miss it entirely. We measure the real post-JavaScript geometry and computed style of every anchor on the page.
  • Zero opacity, hidden visibility, collapsed font size
  • Boxes under 2px in either dimension
  • Absolute positioning beyond the viewport, negative text-indent
  • clip-path erasure and anchors layered behind opaque elements
  • Output: coordinate map, computed style per anchor, selector to remove
Redirect and header forensics+
The last pass reads what happens around the page rather than inside it: status codes, hop chains, canonical conflicts, robots directives and any header that changes depending on who asked.
  • 302 chains that only visitors see
  • Canonical tags pointing at a domain you do not own
  • noindex served selectively to crawlers
  • hreflang loops and self-referencing conflicts
signal catalogue

The eighteen signals, with their weights.

Severity determines how much a signal moves the risk score. Nothing here is a heuristic guess — each row corresponds to a measurable property of the rendered page.

signalhow it is measuredseverityseen in
honest limits

What we deliberately don't flag.

A tool that reports everything is a tool nobody reads. These patterns look suspicious and are usually innocent, so we record them without touching your score.

Hidden nav menus

layout · ignored

Mobile menus, accordions and tab panels legitimately hold links at zero opacity or off-canvas. We check whether the element becomes reachable through a documented interaction before flagging it.

Affiliate links

outbound · recorded only

An affiliate destination is a business decision, not sabotage. We list them so you can see them, but they carry no weight unless they are hidden or you never added them.

Third-party widgets

injection · context-aware

Chat widgets, review embeds and consent tools all inject nodes at runtime. We fingerprint the common ones and only raise a finding when the inserted content is anchors to unrelated hosts.

Slow pages

performance · low weight

Core Web Vitals influence rankings but they are not an attack. They contribute five percent of the score, purely so a report never blames sabotage for something that is just heavy JavaScript.

Point it at a domain and see what comes back.

The first scan needs no account. You will have a score, a cloaking verdict and a hidden-anchor count in about forty seconds.

nsl / report

Anatomy of an audit report.

This is report #A7C‑2291 in full: a real audit of a compromised WordPress site, from the score at the top to the file your developer has to open. Every finding below links back to a measurement, not an opinion.

78risk score
31hidden anchors
71.4%render similarity
38.4sruntime
findings

Nine findings, ordered by what will hurt first.

Open any row for the evidence behind it. Paid reports include the screenshots and DOM snapshots referenced here.

attack timeline

When it started, and how fast it moved.

Reconstructed from daily re-scans. The site was clean for the first eighteen days of the window.

12 Aug · vector opened
12 Aug · first 12 anchors
12
13 Aug · second wave
21
14 Aug · cloaking enabled
19 Aug · rankings fall
‑61%
31 Aug · audit run
31
12 Aug18 Aug24 Aug31 Aug
what ships with it

Five artefacts, all of them yours.

DISAVOW.TXT
4 domainsSearch Console format, comment header with the report ID and generation date.
EVIDENCE BUNDLE
2.1 MBFull-page screenshots under both identities, raw DOM snapshots, hashed and timestamped.
HTTP TRANSCRIPT
47 hostsEvery request, status code and redirect hop recorded per identity.
SELECTOR LIST
31 anchorsExact CSS paths your developer removes, grouped by parent node.
PDF SUMMARY
6 pagesDated, signed, written to be handed to a client, an insurer or a court.
JSON EXPORT
Full schemaThe same data the API returns, for your own dashboards and diffing.
remediation

The order matters more than the actions.

Disavowing before you close the hole achieves nothing, because the links reappear on the next crawl. This is the sequence we give every customer.

Close the vector

day 0 · developer

Strip the base64 payload from footer-widget.js and redeploy. Until this is done, everything else is cosmetic.

Rotate credentials

day 0 · you

FTP, CMS admin and any deploy key. Injection almost always follows a credential leak rather than a code vulnerability.

Re-scan to confirm

day 0 · automated

A clean render is the proof the payload is gone. Keep this report as the before, and the new one as the after.

Upload disavow.txt

day 1 · search console

Only now. Four root domains, uploaded at domain level because the whole host is spam in each case.

File for reconsideration

day 1 · if penalised

Attach the PDF summary. The timestamps in the evidence bundle are what make the case that you were the target, not the author.

Re-scan weekly for a month

ongoing

Reinfection through the same vector is the norm, not the exception. Sentry does this automatically.

Get this for your own domain.

Score, cloaking verdict and anchor count are free. The evidence bundle and disavow file are the paid part.

nsl / how it runs

Thirty-eight seconds, accounted for.

The audit is slower than a source-code scanner because it runs a real browser twice. This page is the infrastructure behind that decision: what happens in each second, on what hardware, and what is destroyed afterwards.

38.4smedian runtime
32chromium slots
99.97%30-day uptime
eu‑west‑3own hardware
stage waterfall

Where the time actually goes.

Measured across the last ten thousand audits. The two renders dominate, which is expected — everything else reads from what they produce.

queue → worker
1.0s
container spawn
1.6s
chromium cold start
1.9s
render A · visitor
6.2s
render B · googlebot
6.1s
text diff
2.3s
layout measurement
4.6s
host resolution
6.5s
redirect audit
3.8s
scoring and export
4.4s
0s10s20s30s38.4s
architecture

Five components, no third parties.

Redis queue

ingest

Every request lands in audit_q before anything is allocated. A traffic burst lengthens the queue rather than exhausting worker memory, and your position is shown to you while you wait.

Free scans share one lane; Sentry and API scans get a priority lane that skips the public backlog.

LXC containers

isolation

Each audit gets a disposable container on our Proxmox cluster, 2 vCPU and 1.5 GB, with no network access to anything but the target and our own queue.

The container is destroyed when the scan finishes. Nothing persists between audits, including cookies, cache and local storage.

Playwright + Chromium

execution

async_playwright drives a current Chromium build with a clean profile. JavaScript runs to completion, XHR is awaited, and lazy content is triggered by a scripted scroll before anything is measured.

This is the reason we find runtime-injected sabotage that source parsers cannot see.

Dual identity

comparison

Both renders start within the same second from the same container, so a difference cannot be explained by timing, geography or a deploy that happened in between.

WebSocket stream

delivery

The worker's stdout is pushed straight to your browser. The log scrolling during a scan is not a simulation of progress — it is the process itself, line by line.

capacity

What the cluster holds.

WORKERS
ct‑1101 → ct‑116464 container slots across four Proxmox nodes in eu‑west‑3.
CONCURRENCY
32 rendersSustained. Peaks queue instead of degrading run time.
QUEUE DEPTH
~7 typicalMedian wait under two seconds outside European mornings.
LINK GRAPH
2.4M domainsRebuilt nightly. Four hours old at worst when your scan runs.
RETENTION
1 hour → 1 yearAnonymous scans are discarded within the hour; account holders choose.
INCIDENTS
41 days agoLast one. Status page shows component-level history.

Watch it run once.

The console shows the real worker log. Thirty-eight seconds is not long to spend finding out what is attached to your domain.

nsl / pricing

Pay per report, or stop having to remember.

Detection is free because a score you cannot act on is worth nothing to us either. You pay when you need the evidence, the domain list and the file you hand to Google.

two months free
comparison

Four plans, line by line.

feature Probefree Forensics€29 / report Sentry€89 / month Agency€249 / month
api usage

Work out what your volume costs.

Sentry includes 500 API scans a month. Beyond that, scans are billed in blocks of one hundred at €7.

Scans per month: 500
Included in Sentry — no overage.
€89per month, all in
questions

The things people ask before paying.

Can I scan a domain I don't own?+
Technically yes, and agencies do it constantly during pitches. Legally that is your responsibility: rendering a page is a request like any other, but automating it against a site you have no relationship with may breach its terms. We ask that you audit what you own or have permission to audit.
Will removing these links restore my rankings?+
We cannot promise that, and anyone who does is guessing. What we can say is that the damage stops accumulating, and that a clean re-scan plus a dated evidence bundle is the strongest material you can attach to a reconsideration request. Recovery timing belongs to Google, not to us.
How is this different from Ahrefs or Semrush?+
They index links across the web and tell you what points at you. We render your own page and tell you what is inside it right now, including content that only appears for crawlers and links positioned where no human can reach them. The two are complementary: they see the backlink profile, we see the page.
What happens to my data?+
Anonymous scans are discarded within the hour. With an account you pick a retention window of 7 days, 30 days or a year. Everything runs on our own hardware in Europe; no third-party AI or analytics provider receives it, and nothing is sold or used for training. You can export or delete it all from Settings.
Do you offer white-label reports?+
On Agency, yes: your logo, your colours, your domain on the PDF and the shareable link. Client-facing reports do not mention us unless you want them to.
Can I cancel?+
At the end of the billing period, with no exit fee and no call. Your history stays available for thirty days in case you come back, then it is deleted.

Start with the free one.

No card, no account, no email. If nothing is wrong you will know in forty seconds and we will never bother you again.

Negative SEOLinksBETA

Your domains, watched while you sleep.

Sentry re-renders every property you own once a day and tells you the moment a link appears that you did not put there.

SOC 2 Type II in progress · GDPR · data stays in eu‑west‑3
← back to negativeseolinks.com

Welcome back

Pick up where your last audit left off.

That doesn't look like an email address.
Use at least 8 characters.
or continue with
Forgot your password? Reset it
No account yet? Create one free
Negative SEOLinks
medi-supplies.example ▾
MF

Overview

last sweep 41 min ago · next in 23h 19m · 2 domains under Sentry

PORTFOLIO RISK
64
+33 in 11 days
HIDDEN ANCHORS
31
across 1 of 2 domains
DISAVOW QUEUE
4
domains pending submission
SCANS LEFT
462
of 500 this month
Risk across your portfolio 90 days ▾
Alert feed all
23 hidden anchors appeared in the footer of medi-supplies.example
Cloaking detected — text similarity dropped to 71.4%
New outbound host: pharm-relay-84.top
klar-optik.de finished clean — 0 findings
disavow.txt regenerated with 4 domains
Monitored domains add domain
domainriskhidden anchorscloakinglast scanstatus
medi-supplies.example7831yes — 71.4%41 min agocritical
klar-optik.de90no — 99.1%6 h agoclean

Domains

2 of 25 slots used on Sentry

domainplancadencerisktrend
medi-supplies.exampleSentrydaily 04:00 UTC78▲ 47critical
klar-optik.deSentrydaily 04:20 UTC9▼ 2clean

Reports

every completed audit, kept for 30 days

reportdomainfinishedruntimerisk
#A7C‑2291medi-supplies.exampletoday, 09:1438.4 s78critical
#A7C‑2118medi-supplies.exampleyesterday36.9 s52degrading
#A7B‑9902klar-optik.detoday, 04:2029.1 s9clean
#A7B‑9781klar-optik.de2 days ago30.4 s11clean

Disavow

4 domains staged · file regenerated 1 day ago

Staged domains
domainanchorsfirst seendofollowaction
pharm-relay-84.top122026‑08‑12yesdisavow
casino-tw9.xyz72026‑08‑12yesdisavow
rx-overnight-shop.click92026‑08‑13yesdisavow
essay-pro-uk.online32026‑08‑14nowatch

API keys

500 scans / month included in Sentry

Active keys
labelkeycreatedlast used
productionnsl_live_9f2c••••••••4a7112 Jun 202618 min agoactive
ci-pipelinensl_live_be40••••••••17c92 Aug 20263 days agoactive
Start a scan from the command line
curl -X POST https://api.negativeseolinks.com/v1/scans \ -H "Authorization: Bearer $NSL_KEY" \ -d '{"url":"https://yourdomain.com","modules":["cloaking","layout","injection"]}' → 202 Accepted {"scan_id":"sc_8812","stream":"wss://api.negativeseolinks.com/v1/scans/sc_8812"}

Billing

Sentry · €89 / month · renews 14 Sep 2026

CURRENT PLAN
Sentry
25 domains, daily
THIS PERIOD
€89
due 14 Sep 2026
SCANS USED
38
of 500
PAYMENT
•••• 4417
Visa, exp 09/28
Invoices
invoicedateamount
NSL‑2026‑081414 Aug 2026€89.00paid
NSL‑2026‑071414 Jul 2026€89.00paid

Settings

account · notifications · data retention

Notifications
Data retention

Reports and DOM snapshots are deleted after the window you choose. Nothing is used to train anything.