Ask HN: Someone is proxy-mirroring my website, can I do anything?

466 points by stanislavb ↗ HN
Hi Hacker News community,

I'm trying to deal with a very interesting (to me) case. Someone is proxy-mirroring all content of my website under a different domain name.

- Original: https://www.saashub.com

- Abuser/Proxy-mirror: https://sukuns.us.to

My ideas of resolution:

1) Block them by IP - That doesn't work as they are rotating the IP from which the request is coming.

2) Block them by User Agent - They are duplicating the user-agent of the person making the request to sukuns.us.to

3) Add some JavaScript to redirect to the original domain-name - They are stripping all JS.

4) Use absolute URLs everywhere - they are rewriting everything www.saashub.com to their domain name.

i.e. I'm out of ideas. Any suggestions would be highly appreciated.

p.s. what is more, Bing is indexing all of SaaSHub's content under sukuns.us.to ¯\_(ツ)_/¯. I've reported a copyright infringement, but I have a feeling that it could take ages to get resolved.

309 comments

[ 46.6 ms ] story [ 7139 ms ] thread
We had a similar situation, though it was just a snapshot. We found out they were hosting using S3, and filed a DMCA request with AWS. It was taken down and hasn’t returned.
Another option would be to use a service like Cloudflare, which offers protections against scraping and other malicious behavior. This can help prevent the proxy-mirror site from being able to access your site's content.

https://blog.cloudflare.com/introducing-scrapeshield-discove...

I have Cloudflare at the front already. The issue is that they are not actively scraping the content but rather mirroring it on demand.
Just an idea but maybe you could cause big loads on their servers by requesting in parallel a large amount of urls where you actively serve a gzipped massive html file that is full of links to your website.

EDIT: or building up on what user zhouyisu says above you can generate your perfect match IP blacklist by calling urls via the abusing site that automatically puts any caller into the blacklist.

I'm not sure how easy would be to serve a "zip bomb" without getting into trouble, but it would be neat
Then where they're coming from should be exceedingly visible in logs (via splunk or whatever), so deny those requests.
If the host (DediPath) is not respecting DMCA notices, one other thing you can do is adding the requester's IP address to every page, eg as a div class. If the responses are live proxied, this will surface the cloner's front-facing IP address, and you can block that (and their ASN) specifically.
Oh, I like this idea. Would be pretty easy to automate it by setting up some script scraping the IP revealed on their site, adding it to the block list as they rotate around. Clever.
Wouldn't they be able to do the same preventing you from scraping the site? They may have many IPs to work with, but you may not?
To extend on this, I wouldn't use clear text for this. Create a HMAC of the IP and add it somewhere in the page, makes it harder to realize what's happening and for the adversary to work around it.
I'm not sure I can understand your advice.
I think it works the following: Assuming the proxy has a different IP pointing to it's client, by inserting the IP it uses to connect to the original server into the HTTP reply (HTML/body code), it can be exposed to the OP. However, since he seems to have access logs and seems to understand the proxy requests pretty well, I wonder how it actually helps.
Add a comment (or attribute or JS with a string literal) to your HTML that contains IP address of whoever requested the page. Obscure it somehow so it's not obvious that the HTML contains the IP address. Then check source code of the copy, and you'll see who requested it. You can then go after that IP.

BTW: if they're removing/replacing domain name of your site, try obscuring it with HTML entities. This may dodge simple find'n'replace.

That's clever, and I just understand after a while.

Now let's say that your website will show the ip of whoever visit it, in one of textbox. When you access it it shows your ip. When the proxy sever access it it shows the proxy sever's ip. When you access the proxy site, the proxy site will access your site, having their ip on one of the text box, then return the page with their ip to you.

The more advanced method is to encrypt the ip and put it hidden somewhere, on later for you to decrypt it, get the ip and black list them.

Maybe some logic honeypot would be good, such as a infinite content paging list with some random trigger hidden at pages with non-sense titles. When one IP hits these triggers, it is automatically banned.

Bots will trigger it by walking through all pages, but real human would not click in since the paging is non-sense and titles are non-sense.

Yeah, but I don't want to ban bots. Also, they are not actively crawling anything, but rather mirroring the content on demand. At least that's my observation so far... thanks anyways.
If you have a trademark, domain takedown always works.
That isn't neccesary true. While I definitely agree that the OP should pursue that path, many providers are in other jurisdictions.
Add a link rel="canonical" to your pages as well, it should give engines a hint that your domain is the legit one.

https://webmasters.stackexchange.com/questions/56326/canonic...

I noticed that the other domain is hotlinking your images. So you can disable image hotlinking, by only allowing certain domains as the referers. If you block hotlinked images then the other domain will not look as good. Remember to do it for SVGs too.

https://ubiq.co/tech-blog/prevent-image-hotlinking-nginx/

Finally I also see they are using a CDN called Statically to host some assets off your domain. You can block their scrapers by user agent listed here:

http://statically.io/docs/whitelisting-statically/

I think they are replacing all mentions of saashub.com with their domain. Also, I'm not using statically.io, that's something they are prepending in front of all images. Automatically.
But Statically isn't forwarding the User-Agent of the visitor, and they publish the list of User-Agents that they use, which you can block.
It's adding the CDN for some of the images but not all of them, so you'd have to cover both
Sometimes the replacement is done with simple pattern matching. Try different forms of encoding you domain to see if you can get through their replacement.
If they are stripping all JS, you can make the page work only with JS enabled :/
Don't block their IPs, but rather return them subtly wrong content that isn't broken at the first glance. Insert typos, replace important terms, inject nonsense technobabble, make URLs point to wrong pages, inject off-topic SEO-spammy keywords that search engines will see as the SEO spam they are.
1. Create fake url endpoint. And go to that endpoint in the adversary's website, when your server gets request, flag the ip. Do this nonstop with a script.

2. Create fake html elements and put unique strings inside. And you can search that string in search engines for finding similar fake sites on different domains.

3. Create fake html element and put all request details in encrypted format. Visit adversary's website and look for that element and flag that ip OR flag the headers.

4. Buy proxy databases, and when any user requests your webpage, check if its a proxy.

5. Instead of banning them, return fake content (fake titles and fake images etc) if proxy is detected OR the ip is flagged.

6. Don't ban the flagged ip's. She/He's gonna find another one. Make them angry and their user's angry so they give up on you.

7. Maybe write some bad words to the user on random places in the HTML when you detect flagged ip's :D So the user's will leave the site and this will reduce the SEO point of the adversary. Will be downranked.

8. Enable image hotlinking protection. Increase the cost of proxying for them.

9. Use @document CSS to hide the stuff when the URL is different.

10. Send abuse mail request to the hosting site.

11. Send abuse mail request to the domain provider.

12. Look for the flagged IPs and try to find the proxy provider. If you find, send mail to them too.

Edit: More ideas sparkled in my mind when I was in toilet:

1. Create fake big css files (10MB etc). And repeatedly download that from the adversary's website. This should cost them too much money on proxies.

2. When you detect proxy, return too big fake HTML files (10GB) etc. That could crash their server if they load the HTML into the memory when parsing.

I like how you think. These are all great ideas!

Reminds me of a time some real estate website hotlinked a ton of images from my website. After I asked them to stop and they ignored me I added an nginx rewrite rule to send them a bunch of pictures of houses that were on fire.

For some reason they stopped using my website as their image host after that.

What a sure-fire way to toast them! Kudos!
Bummed that I can upvote this only once. Excellent work.
Is the primary motivator to do this?

I'm curious if they are stealing anything else, e.g. are they selling ads/tracking, do they replace order forms with their own...

because I asked them to stop doing it, and they didn't. Technically they were stealing my bandwidth.

Also to teach them an important lesson about the internet.

haha, they're just lucky you didn't introduce them to Goatse
well actually...

there was another time a site hotlinked to a js file. After asking them to stop, i found that they had a contact form with a homebrew captcha which created the letters image like http://evilsite.com/cgi-bin/captcha.jpg?q=ansr

A little while later, their captcha form had a hidden input appended with the correct answer value, and the word to solve was changed to a new 4 letter word from a dictionary of interesting 4 letter words. The form still worked because of the hidden input. I might have changed the name on the "real" input also.

LOL! Thank you for the laugh. This is great.
#5 and #6 are key. Don't try to block them directly, just get them delisted. When you've worked out a way to identify which requests belong to the scammer, feed them content that the search engines and their ad partners will penalize them for.
Signal boosting suggestion #1 here. Great idea.

Additionally if they decide to blackhole the fake/honeypot url, since you mentioned they pass along the user agent, you could mixin some token in a randomized user agent string that your scraper uses so that you could duck-type the request on your end to signal when to capture the egress ip.

In my search for this I found @document isn't super supported [0] I suggested something like:

    a[href*= "sukuns.us.to"] {
     display:none; 
    }
Then use SRI to enforce that CSS.

[0]: https://caniuse.com/mdn-css_at-rules_document

Seems like it would be fairly easy to use this pseudo selector, and apply it to every element on the page. Making them show up as empty to the user
You could add a data attribute to the html tag of the document with the current URL, I.E.

  <html data-path="https://www.saashub.com/about">
then hide the full page with:

  html {display: none;}
  html[data-path*="saashub.com"] {display:block;}
This seems quite elegant and easy. Obviously in addition to other measures, but I like it.
Honestly this is my favorite HN post in a while I've had a lot of fun thinking over this challenge.
How about something like...

    body[href*= "<OFFENDING URL>"] {
        background-image: url("http://goatse..."); 
    }
Ala: http://ascii.textfiles.com/archives/1011
Or just make the whole page rotate

    body[href*= "<OFFENDING URL>"] {
      animation: rotation 20s infinite linear;
    }

    @keyframes rotation {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(359deg);
      }
    }
We're trying to punish the people running the proxy mirror, not the users who stumble upon them just trying to use the site
In that case, write some JS, that wanders around the Hubble site, randomly downloading full-res TIFF images for the background, or that randomly displays Disney images.
You could look at it as trying to get them blocked by search engines. Can you detect when they're proxying a search bot as opposed to a user? As for punish, you don't have to make it eye-bleach, just enough to make it firmly NSFW so nobody can get any business value from it, or even use it safely at work.

A little soft NSFW would also greatly accelerate them being added to a block list, especially if you were to submit their site to the blocklists as soon as you started including it. You can include literally anything that won't get you arrested. Terrorist manifestos, the anarchists cookbook, insane hentai porn... Use all those block categories - gore/extreme, terrorist, adult, etc.

I know this is just a game that never ends, but if they're already rewriting the HTTP requests what's stopping them from rewriting the page contents in the response?

SRI is for the situation where a CDN has been poisoned, not this.

It might not explicitly be what SRI is meant for but it'll narrow the proxy's options to:

A. Blank page

B. Let the find and replace update the CSS. Generate new hashes in the HTML.

C. Find someone new to pick on.

B is time and potentially computationally expensive, so it makes C a better option.

A doesn't work because B doesn't prevent the attacker from regexing out the hash altogether and changing the domain name in the tags to their own.
If they're rewriting html, I guess sanitizing css won't be beyond them.
> 5. Instead of banning them, return fake content (fake titles and fake images etc) if proxy is detected OR the ip is flagged.

> 6. Don't ban the flagged ip's. She/He's gonna find another one. Make them angry and their user's angry so they give up on you.

There's a popular blog that no longer gets linked on HN.

The author didn't like the discussions HN had around his writing, so any visitors with HN as the referer are shown goatse, a notorious upsetting image, instead of the blog content.

Goatse? I assume you're referring to jwz - that blog shows a testicle in an egg cup if it sees a HN referrer.
Yeah, jwz. Looks like I got mixed up - goatse has been a popular choice for this kind of thing, but jwz went with a different image.

Fortunately, there are many upsetting images for the OP to choose from!

Does anyone not have their referer header supressed or faked?
I have never considered faking or suppressing my referer header. I don't know why I would care. I suspect I'm in the company of well over 99% of all internet users.
I strip the referrer generally via https://wiki.mozilla.org/Security/Referrer, unfortunately it breaks a small number of sites very badly, such as web.archive.org and a few others. some of them claiming it was done to combat scraping.
Breaking is only part of the problem. The pages that rely on the referer header take it for granted and do not implement any meaningful error handling. They just die a horrible death, instead of responding with an error message stating that they need a referer.

One bad example is relying on the referer only for log-out, everything else works. That site also runs massive js on log-out, as if it really needs to rely on explicit log-out, and not just the user disappearing.

> Maybe write some bad words to the user on random places in the HTML

> Create fake big css files (10MB etc). And repeatedly download that from the adversary's website. This should cost them too much money on proxies.

Be careful when doing things like this, including the shock image option mentioned in other comments, as then it could become an arsehole race with them trying to DoS your site in retribution. Then again, going through more official channels could also get the same reaction, so…

> When you detect proxy, return too big fake HTML files (10GB) etc. That could crash their server if they load the HTML into the memory when parsing.

Make sure you are setup to always compress outgoing content, so that you can send GBs of mostly single-token content with MBs of bandwidth.

Why return big files when you can return small files at excruciatingly slow speeds? modems are hot again!
that's probably the best advice. Instead of denying the proxy, just make it shitty to use for the end-user.
Seems like a good use case for a zip bomb. Return some tiny gzipped content that expands to 1gb.
Yeah. Their proxy is parsing the HTML and stripping it / modifying it, so they're obviously unzipping the responses on their servers. Create the honeypot endpoint, and if you get a request from that endpoint, reply with a zip bomb.

Then, write a little script that repeatedly hits that honeypot URL. I quite like this idea.

Awesome, do post a follow-up on HN, I want to hear how this war with the proxy asshats plays out.
I really like #9, this seems like a simple way to make your site unusable except via the methods you desire.
I remember years ago there was a way to DDoS a server by opening the connection and sending data REALLY slow, like 1 byte a second. I wonder if there is a way to do the opposite of that, where ever request is handed off to a worker which slow enough to keep the connection alive. I doubt this can scale well, but just a thought.
you can have some fun with nginx if you can identify on your backend whether the request is coming from a malicious source, e.g. with X-Accel-Limit-Rate
Going defcon3 on proxies

You can also write some obfuscated inline JavaScript that checks the current hostname and compares to the expected one and redirects when not aligned.

point no.1 will do. that's the solution.
These are the best ideas, especially SEO poisoning and alternate images. If their point is to steal content and rankings then poisoning the well should discourage this in the future. I suspect their actual goal is to have a low-effort high SEO site to abuse as a watering hole for phishing attacks.

As a side note, their domain is linked in this thread so they are seeing HN in their access logs and probably reading this. It should make for an interesting arms race. Or red/blue team event.

They said the attacker was passing through the client's user agent. If they get a user agent that is GoogleBot, they could check if the requesting IP is actually a valid Google data centre (there is a published list of IPs). If the IP is not Google directly, they could return a blank page therefore causing Google to index nothing through the mirrored site.
This is a good idea, though it may be short lived since the attackers are likely reading this due to the referrers in the logs. They may add an ACL to counter this but it might be interesting to see how long that works.
Shadow nefarious techniques are the best. Don't give them clear indications that there is a problem.

For example, I had an app developer start stealing API content, so once I determined points to key from them, instead of blocking them I simply randomized the API content details returned to their user's apps.

Hey, API calls look good, the app looks like it is working, no problem right? Well, the users of the app were pissed and the negative reviews rolled in. It was glorious.

Serious question — is there a way to defend from this "stealing the API" thing? E.g. building an authentication of some sort and then including a key with your app?
Of course HN doesn’t like anything that’s reminiscent of DRM, but Apple’s App Attest and Google’s Play integrity API can help dispense online services to valid clients only.
(comment deleted)
Passive Aggressive FTW. These are all fantastic ideas.
> Create fake big css files (10MB etc). And repeatedly download that from the adversary's website. This should cost them too much money on proxies.

Doesn't that also cost you an equal amount? You'll be serving them an equal amount that they proxy to the end user.

It's not even necessarily a cost for them; you're assuming that the host is owned and paid for by the abuser. If it's simply been hijacked (quite possible), you're just racking up costs for another victim.

Fake 10GB html can be a zip bomb?
Oh, I love these. I will use some of them. Many thanks!
(comment deleted)
> 1. Create fake big css files (10MB etc). And repeatedly download that from the adversary's website. This should cost them too much money on proxies.

Nope, since anybody doing this and it has at least minimum intelligence are using residential botnets as proxies.

Look at your traffic logs and see if you can't fingerprint the scraper. Should be relatively easy since they're mirroring your entire site.

Then instead of blocking the fingerprint, poison the data. Introduce errors that are hard to detect. Maybe corrupt the URLs, or use the incorrect description or category. Be creative, but make it kind of shit.

It's easy to work around blocks. Working around poisoned data is much harder.

This... there are definitely aspects of the proxy that they aren't configuring or are unaware of.

i.e. ssl_cipher, http_x_requested_with, http_accept... and the order of all headers supplied... the casing of all headers supplied... TLS client HELO.

It is relatively easy, if you have enough signals, to essentially create a fingerprint that they won't understand how it works. Yet it will be effective at blocking it regardless of the IP.

Once you add enough of these together it will be hard for them to get around it without being obvious as they do so.

Super aggressive... those same fingerprints will reveal legit browser traffic and the fingerprints for things like Google-bot... so you could go towards a whitelist rather than blocklist. But this is a place you'd have to actively manage as new variations arise constantly.

This is some really cool anti-scraping inside baseball. Is it safe to say that Cloudflare uses these techniques for weeding out bots?
It's safe to say that if you have enough signals from every possible layer (of which the above a barely a few) that it becomes trivial to build a model that can identify the majority of bots.

However, then you're left with the really hard problem of when real browsers are used. But hey, you went a long way before you had to actually look at traffic patterns and in the meantime you've significantly raised the costs for those operating the bots.

It's also worth noting that if you really get enough signals, that bot writers cannot control them all. Everyone can rewrite a HTTP header, but can you pick the right HTTP headers in the right order with the right TLS cipher and TLS HELO to appear to be the same as Chrome on Windows? Good luck.

What about steganography?

If you change subtle details about spelling, spacing, formatting, etc by the source IP, then you can look at one of their pages and figure out which IP it was scraped from.

Then, just add goatse to all pages requested by that IP. Alternatively, replace every other sentence with GPT-generated nonsense.

EDIT: it should be quite easy to use JS to fingerprint the scraper. The downside is that you will also block all NoScript users.

Warning: Don't visit the proxy mirror at work, I was redirected to xcams/adult content.
weird, wasn't the case here.
The mirror is injecting their own ads. My guess is it was just a malicious ad forcing the redirect. It could still happen, but it doesn’t appear to be the main intention of the mirror site.
Quick and easy first:

1) Add a watermark to your images when they proxy to you.

Stolen image from {url}

2) Add a js script when the url differs from yours and display a message + redirect

What about a slightly alternative approach, where instead of trying to block the abuser, you try to make it clear to end users what the real website is? E.g. in your logo image, include the real domain name "saashub.com". Have some introduction text on your home page "Here at saashub.com, we compare SaaS products ...." When your images are hotlinked, replace them with text like "This is a fraudulent website, find us at saashub.com". Anything that can make it obvious to end users that they're on the wrong website when they visit the abuser's URL.

By the way, I've also reported the abuser as a phishing/fraud website through https://safebrowsing.google.com/safebrowsing/report_phish/?u...

Not sure if this would help since:

> 4) Use absolute URLs everywhere - they are rewriting everything www.saashub.com to their domain name.

Embed the welcome text in an image then!
Try some things like sa(zero-width-space)ssh<b></b>ub.com
Setup Cloudflare on the domain and turn on “bot fight mode”.

If the TLS ciphers the client proposes for negotiation doesn’t align with the client’s User-Agent they get a CAPTCHA.

I would suspect that whoever is doing this proxy-mirroring isn’t smart enough to ensure the TLS ciphers align with the User-Agent they’re passing through.

I would agree with the above, as an easier version of TLS fingerprinting. One could also ise nginx/haproxy to extract enough TLS info, and detect requests xoming through proxy Magic string: JA3 fingerprint
On the free tier, does bot fight mode do anything other than simply detect bots based on JavaScript detections?
(comment deleted)
Generate your pages from Javascript.
I'm not going to focus on the problem here. I just want to say that I like the idea behind your website, a good source of market research. Bookmarked it.
I wonder what they get out of this. Injecting ads perhaps?
I saw another comment saying that the site sometimes redirects to adult content sites.
Landing place for a phishing campaign. See: watering hole attack.
(comment deleted)
When someone did it to us we replaced the served content with ads for our site.
That sounds like the most elegant approach so far.
Their domain is likely to be considered hostile, and drop in Google results.
Block all requests having "https://sukuns.us.to" as "Referer" HTTP header.