The Lean Cheat Sheet for When You Can’t Avoid Plugins

Download the FREE Plugin Cheat Sheet: Proven lightweight picks to reduce page weight, boost speed, and streamline your WordPress stack.

Lean Plugin Cheat Sheet Preview

How to Prevent Image Hotlinking in WordPress

Ever noticed your site slowing down without an obvious cause? One culprit could be hotlinking, when another site embeds your images, videos, or files directly from your server. Each time their page loads, your hosting does the work, draining bandwidth, adding to your costs, and slowing your pages for real visitors.

It’s essentially “bandwidth theft”: your resources powering someone else’s content. Beyond the hit to performance and budget, it’s wasteful for the planet – every unnecessary request uses energy across servers, networks, and devices. Blocking hotlinking is a quick win that makes your site faster, leaner, and more sustainable.

Green hosting server icon

Ready for Faster, Greener Hosting?

We recommend Krystal - fast, reliable, powered by 100% renewable energy. It's a host we trust and a smart move for a cleaner web.

How to check if hotlinking is happening on your site

Catching hotlinking early saves you from wasted bandwidth and awkward surprises on your hosting bill. The trick is knowing where to look, and how to tell a genuine embed from someone siphoning your media.

Spot suspicious traffic using logs and CDN analytics

Your hosting panel often has a Raw Access or AWStats feature that lists every file request and its referring site. If you spot domains you don’t control, that’s a hotlinking red flag. Using a CDN like Cloudflare? Their analytics dashboard will show which domains are requesting your images, videos, or PDFs. When one of them isn’t you, it’s time to investigate.

Understanding HTTP referers and blank requests

Most hotlink detection relies on the HTTP referer – the URL of the page requesting your file. But not every suspicious request comes with a clear tag. Privacy tools, some RSS readers, and deliberate masking can send a blank referer. Blocking these outright can backfire, breaking legitimate embeds or partner feeds, so weigh the risks before hitting “deny all.”

Quick tools for confirming media theft

If you’re unsure, run a reverse image search to see where your graphics appear, or use a free HTTP header checker to watch requests in action. Anything that points back to your domain while loading on someone else’s site is likely hotlinking. These checks don’t take long, and they give you the evidence you need before choosing a fix.

Decision shortcut:

  • Shared hosting → cPanel or plugin
  • VPS/dedicated → .htaccess or Nginx rules
  • CDN-heavy → Cloudflare or AWS WAF/S3 signatures
Flowchart showing how to choose the right hotlink protection method based on hosting type, with three branches for shared hosting, VPS/dedicated server, and CDN usage on a black background with lime green connectors.

WordPress plugin options without the extra baggage

Use lightweight plugins like AIOS or Hotlink File Prevention. Avoid bloated security suites.

Enable cPanel Hotlink Protection, add trusted domains (your own, staging, and partners), and block everything else.

Server-level fixes with .htaccess or Nginx rules

Add referer checks to .htaccess on Apache or use valid_referers in Nginx. Strong control, but syntax errors can cause downtime, so test on staging first.

Apache (.htaccess) – allow your sites + Google Images/Pinterest, block the rest:

# Enable rewriting
RewriteEngine On

# Skip if referrer is empty? (comment out next line to block blanks)
RewriteCond %{HTTP_REFERER} !^$ [OR]

# Allow your domains
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?example\.com/ [OR]
RewriteCond %{HTTP_REFERER} ^https?://(staging\.)?example\.com/ [OR]

# Allow common referrers that help you
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?google\.[^/]+/ [OR]
RewriteCond %{HTTP_REFERER} ^https?://(images\.)?google\.[^/]+/ [OR]
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?pinterest\.[^/]+/ [OR]
RewriteCond %{HTTP_REFERER} ^https?://(i\.)?pinimg\.com/ 

# Block hotlinking for common asset types
RewriteRule \.(jpe?g|png|gif|webp|svg|mp4|pdf)$ - [F,NC,L]

Replace example.com with your domains. If you want to block blank referrers, remove the first RewriteCond line. Keep the allowed referrers list short.

Nginx – equivalent rule using valid_referers:

# Inside your server block
location ~* \.(?:jpe?g|png|gif|webp|svg|mp4|pdf)$ {
    valid_referers none blocked server_names 
                   *.example.com example.com 
                   *.staging.example.com staging.example.com
                   *.google.* google.* images.google.*
                   *.pinterest.* pinterest.* *.pinimg.com;

    if ($invalid_referer) { return 403; }
}

Keep the list minimal and tailored. Start with none blocked to allow legitimate blanks (RSS/privacy tools). If previews break, remove none and explicitly allow only what you need.

Turn on Scrape Shield to block at the CDN edge. Use Workers or custom rules for exceptions or tokenised URL checks.

Cloudflare Firewall Rule (block hotlinking except approved referrers):

(http.request.uri.path matches "\.(?:jpe?g|png|gif|webp|svg|mp4|pdf)$")
and not (
  http.referer contains "example.com" or
  http.referer contains "staging.example.com" or
  http.referer contains "google." or
  http.referer contains "pinterest." or
  http.referer contains "pinimg.com"
)

Action: Block (or JS Challenge while testing).

Cloudflare Worker (return 403 when referrer not allowed):

export default {
  async fetch(request) {
    const url = new URL(request.url)
    const isAsset = /\.(jpe?g|png|gif|webp|svg|mp4|pdf)$/i.test(url.pathname)
    if (!isAsset) return fetch(request)

    const ref = request.headers.get('referer') || ''
    const allow = [
      'example.com',
      'staging.example.com',
      'google.',
      'pinterest.',
      'pinimg.com'
    ]
    const ok = allow.some(d => ref.includes(d))
    return ok ? fetch(request) : new Response('Hotlink blocked', { status: 403 })
  }
}

Deploy on the media route only (e.g., /wp-content/uploads/*) to keep logic tight.

AWS CloudFront + WAF referer checks and S3 signed URLs

Restrict access with WAF referer rules or use signed URLs to make stolen links expire.

AWS WAF rule (allow list of referrers, else block) – regex example:

Allow only matching referrers → (?i)(example\.com|staging\.example\.com|google\.|pinterest\.|pinimg\.com)
If URI ends with image/video extensions AND Referer header does not match → Block.

S3/CloudFront origin hardening (avoid direct S3 hotlinks):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontOnly",
      "Effect": "Allow",
      "Principal": {"Service": "cloudfront.amazonaws.com"},
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*",
      "Condition": {
        "StringEquals": {"AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID"}
      }
    }
  ]
}

Use Origin Access Control (OAC) or OAI so objects are only fetchable via CloudFront, then enforce referrer rules in WAF. For paid/premium files, enable Signed URLs with short expiries.

Restrict access with WAF referer rules or use signed URLs to make stolen links expire.

Blocking hotlinking is great, until you realise you’ve also blocked the very channels that help you get found. A smart setup keeps freeloaders out while letting trusted sources and legitimate previews through.

Allow-list Google Images, Pinterest, and trusted partners

If search visibility matters, you’ll want Google Images to keep indexing your media. Likewise, Pinterest and other partner platforms may drive traffic your way. Add these domains to your allow-list so their previews and embeds still work, while everyone else gets blocked.

ServiceImpact if blockedAllow-list pattern
Google ImagesImages disappear from image searchgoogle. or images.google.
PinterestPins lose preview imagespinterest. or pinimg.com
LinkedInNo image in link previewlinkedin.com
FacebookNo image in link previewfacebook.com

Social platforms like Facebook, X, or LinkedIn pull preview images when you share a link. If your protection is too strict, those previews break, making your posts look bare and less clickable. Always test a few recent blog posts in your key social channels after enabling protection.

Handle RSS feeds and blank referers

Some RSS readers and privacy-focused browsers strip the referer header entirely, which can cause your own content feeds to fail. If you see a lot of blank referers in your logs, whitelist them or apply a softer rule for specific content types like .jpg and .png.

Test before you block – staging site best practices

Whether you’re using cPanel, .htaccess, Nginx rules, or CDN controls, apply them in a staging or test environment first. That way, you can check your live site, social previews, and partner integrations without risking broken content for your visitors. A few minutes of testing can save hours of cleanup later.

Hotlinking isn’t a “set it and forget it” job. New files, site changes, and even hosting migrations can open up fresh opportunities for freeloaders. Ongoing monitoring keeps your protection working without tripping up legitimate uses.

Monitor with logs, analytics, and CDN reports

Your hosting logs are the first line of defence, they show which domains are requesting your files. Pair them with CDN analytics (like Cloudflare’s traffic reports) to spot any spikes in requests from unknown sites. Reviewing these monthly is enough for most sites, but if you run high-traffic media, check weekly.

Advanced tactics – tokenised URLs and watermarks

For premium or high-value content, tokenised URLs (sometimes called signed URLs) create unique, time-limited links that hotlinkers can’t reuse. If your goal is brand visibility rather than secrecy, watermarking images means that even if they’re hotlinked, your name stays attached.

Persistent offenders sometimes need a stronger nudge. A DMCA takedown notice (or your region’s equivalent) can force the removal of infringing content. Your hosting provider or CDN often has a reporting channel to make this process quicker.

Track savings in speed, bandwidth, and CO₂

The easiest way to prove hotlink protection is working is to measure before and after. Look at total bandwidth served, LCP/TTFB scores, and your site’s carbon footprint (you can use the website carbon calculator). It’s motivating to see load times improve, bloat cut, and grams of CO₂ per page drop, especially if you report these wins to your team or clients.

MetricBeforeAfter
Bandwidth use (GB/month)12074
LCP (sec)2.72.1
CO₂ per page (g)0.850.52
Green service optimisation icon

The Quick Fix for a Slow, Heavy Site

We optimise your site for speed, efficiency and sustainability. No rebuild. No delays. Just better performance and a lighter footprint.


Conclusion – faster, leaner, and in control

Blocking hotlinking isn’t just about stopping digital freeloaders. It’s about keeping your site loading fast for real visitors, protecting your hosting budget, and trimming the invisible carbon costs of wasted data transfers. Whether you’ve used a quick cPanel toggle, a few lines of server code, or CDN-level rules, the result is the same, your content works for you, not for someone else’s audience.

Next Steps

Pick one method today, apply it, and then watch your metrics over the next week. Check bandwidth usage, page speed, and carbon footprint to see the difference.

Profile photo of Neil Beckett

Neil Beckett

Neil is the founder of LeanWebs, with over ten years of experience in WordPress development. What started as a love for site speed turned into a mission to build faster, lighter, more sustainable websites.