Start Free
Loading article…
WordPress Tips

How to Prevent Hotlinking of WordPress Media (Server, Cloudflare, Bunny and CloudFront)

15 min read

If you want to prevent hotlinking WordPress media, the right fix depends on where your files are served from. A rule in .htaccess protects images on your web server, but once media is offloaded to a bucket or served through a CDN, those requests never reach WordPress, and the protection has to move to the CDN.

This guide explains what hotlinking costs, how to spot it, and how to block it on Apache, nginx, Cloudflare, Bunny and Amazon CloudFront, with the exact settings each vendor documents. It also covers the caveats that trip people up: blank referrers, RSS readers, social previews and Google Images.


What Hotlinking Is

Hotlinking happens when another website displays your image, video or file by pointing directly at its URL on your server or CDN. The visitor sees the file on their site, but your server or CDN delivers it and you pay for the bandwidth.

prevent hotlinking WordPress: Hotlink protection key facts
Hotlink protection key facts

Common examples

  • A forum post that embeds your product photo with an <img> tag.
  • A scraper site that copies your articles and keeps your image URLs.
  • A competitor using your infographic without downloading it.
  • An app or site playing your MP4 file directly in its own player.
  • Download sites linking straight to your PDFs or ZIP files.

What it is not

Linking to your page is not hotlinking; that sends you visitors. Search engines showing thumbnails, feed readers showing your posts and social networks building link previews all request your files too, and you usually want to allow them. Blocking those by accident is the most common mistake, and we cover it in the caveats section.

What Hotlinking Costs You

The cost depends on where the file is served from. On shared hosting it uses bandwidth and server resources. On metered cloud storage or a CDN, it is a line on your bill.

Price of 1 TB of hotlinked traffic

Here is what 1 TB (1,000 GB) of delivered traffic costs at list prices, checked September 2026:

Where the file is served fromRateCost of 1 TB
Amazon S3, direct, first 10 TB$0.09 per GB$90
CloudFront, US and Europe, after the free 1 TB$0.085 per GB$85
Bunny CDN, Asia and Oceania$0.03 per GB$30
Bunny CDN, Europe and North America$0.01 per GB$10
Bunny Volume network$0.005 per GB$5
Cloudflare R2Free egress$0 egress, request charges may apply

Sources: S3 pricing, CloudFront pay-as-you-go pricing, Bunny CDN pricing and R2 pricing. S3 includes 100 GB of free transfer per month across AWS, and CloudFront’s always-free tier includes 1 TB, so small amounts may cost nothing.

How fast it adds up

  • A 500 KB image shown 100,000 times on a busy forum is about 50 GB.
  • A 150 MB video played 10,000 times on someone else’s site is about 1.5 TB.
  • Images are rarely the problem on their own. Large files, video and downloads are where hotlinking hurts.

The costs that are not on the bill

  • Slower pages for your own visitors when your server is busy serving someone else’s.
  • Hitting a hosting plan’s fair use limit or bandwidth cap.
  • Your work appearing on sites you would not choose to be associated with.
Key point: R2’s zero egress fee removes most of the financial risk for images. Protection still matters for video, large downloads, and any provider that bills per GB.

How to Detect Hotlinking

Before writing rules, confirm you have a problem and find out who the hotlinkers are. You may also discover legitimate sites you want to allow.

Where to look

SourceWhat to check
Web server access logsThe referer field on image and video requests that is not your domain
CDN analytics and logsTop referrers, top files and bandwidth by file
Bucket or CDN billA sudden jump in egress that does not match your traffic
Reverse image searchYour images appearing on other sites
Most-requested filesOne image or video with far more requests than its page gets views

A quick log check

On a server with the common combined log format, this lists the top external referrers for images. Replace example.com with your domain:

grep -Ei '\.(jpe?g|png|gif|webp|avif|mp4)' access.log | awk -F'"' '{print $4}' | grep -v 'example.com' | sort | uniq -c | sort -rn | head -20

Entries showing - have no referer. Those are usually direct visits, apps, privacy tools or crawlers, not hotlinking sites.

Offloaded media changes where you look

If your media is served from a bucket or CDN, your server logs will not show those requests at all. Use the CDN’s logs or analytics instead. For how offloading and CDNs fit together, see media offload vs CDN.

How the Referer Header Works

Almost every hotlink protection method checks the HTTP Referer header (spelt with one “r” in the HTTP standard). When a browser loads an image on a page, it usually tells the server which site the page is on.

What browsers send today

According to MDN’s Referrer-Policy reference, the default policy is strict-origin-when-cross-origin:

  • Same-origin requests send the full URL.
  • Cross-origin requests send only the origin, such as https://www.example.com/.
  • Requests from HTTPS to HTTP send no referer at all.

What that means for your rules

  • If media is on cdn.example.com and your site is www.example.com, the CDN sees only https://www.example.com/. Match on the domain, not a page path.
  • Allow every hostname that shows your media: www, the bare domain, staging, and any subdomain sites.
  • A site can set Referrer-Policy: no-referrer, so blank referrers are normal and not proof of abuse.
  • The header is easy to fake. The nginx referer module docs warn that referers can be fabricated easily, so referer checks stop casual embedding, not determined downloaders.

Apache: .htaccess Referer Rules

If images are still served from your WordPress server on Apache, a mod_rewrite block in .htaccess is the classic way to prevent hotlinking WordPress uploads. Put it above the WordPress rules and replace example\.com with your domain:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://([^/]+\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://([^/]+\.)?google\. [NC]
RewriteRule \.(jpe?g|png|gif|webp|avif|mp4)$ - [F,NC,L]

What each line does

  • The first condition allows blank referers, so direct visits, apps and privacy tools still work.
  • The second allows your domain and any subdomain.
  • The third allows Google, so image search keeps working. Add other services you want to allow.
  • The rule returns 403 Forbidden for matching file types from anyone else.

The syntax is in the Apache mod_rewrite documentation. Keep a copy of .htaccess before editing, because a typo can take the whole site down with a 500 error.

When .htaccess stops working

  • Offloaded media: files served from a bucket or CDN URL never touch Apache.
  • CDN caching: if a CDN caches your images, it serves the cached copy to everyone without asking your server, so the referer check only runs on cache misses.
  • nginx in front: many hosts serve static files from nginx before Apache sees the request.

nginx: valid_referers

On nginx, the valid_referers directive sets the $invalid_referer variable, which you can use to return 403. Add a location block like this to your server block:

location ~* \.(jpe?g|png|gif|webp|avif|mp4)$ {
  valid_referers none blocked server_names *.example.com ~\.google\.;
  if ($invalid_referer) { return 403; }
}

The parameters

ParameterMeaning
noneNo Referer header at all
blockedHeader present but stripped by a firewall or proxy
server_namesYour configured server names
*.example.comWildcard hostnames
~\.google\.A regular expression, here matching Google domains

If your existing config already has a location block for static files with caching headers, add the referer lines inside that block rather than creating a second one. The same limits as Apache apply: once media is offloaded or cached at a CDN, the rule has to move to the edge.

Cloudflare Hotlink Protection and Custom Rules

Cloudflare offers two approaches: a one-click toggle and flexible WAF custom rules. Both work at the edge, so they also protect cached files and media served from an R2 custom domain.

prevent hotlinking WordPress: Build a safe referer rule
Build a safe referer rule

The Hotlink Protection toggle

Per Cloudflare’s Hotlink Protection documentation, the feature denies requests when the referer does not include your domain and is not blank. You switch it on under Security → Settings.

  • It only covers gif, ico, jpg, jpeg and png. WebP, AVIF, SVG, MP4 and PDF are not covered.
  • Blank referers are allowed.
  • Files in any folder named hotlink-ok are exempt, which suits a press kit.
  • Configuration rules can switch it off for specific paths or hostnames, or apply it only to certain hostnames.

The pages we checked do not state which plans include the toggle, so confirm in your dashboard.

WAF custom rules for everything else

For modern formats and video, use a custom rule with the Block action. Cloudflare’s own partner exemption example uses the http.referer field. A version for media might look like this:

(http.request.uri.path.extension in {"jpg" "jpeg" "png" "gif" "webp" "avif" "mp4" "pdf"} and http.referer ne "" and not http.referer contains "example.com" and not http.referer contains "google.")

Cloudflare planCustom rulesRegex in rules
Free5No
Pro20No
Business100Yes
Enterprise1,000Yes

Limits are from the custom rules documentation, checked September 2026. One rule is enough for most sites, so the Free plan works.

R2 needs a custom domain

Cloudflare’s R2 public buckets documentation says r2.dev URLs are rate-limited and meant for development, and that WAF custom rules, caching and bot management need a custom domain. Our guide to setting up a Cloudflare R2 custom domain walks through it, and Cloudflare R2 WordPress errors helps if images stop loading after you add rules.

Bunny: Allowed Referrers and Token Authentication

Bunny builds hotlink protection into every pull zone. If you serve media from Bunny Storage through a pull zone, this is where to set it.

Allowed and blocked referrers

According to Bunny’s hotlink protection docs, you add allowed referrers in the pull zone’s Security settings. Requests from other domains get a 403.

  • Wildcards like *.example.com cover subdomains, but add the root domain separately.
  • Blank referers are allowed by default.
  • Once allowed referrers are set, a Block Direct URL File Access option can block empty referers. Bunny warns that empty referers come from legitimate sources such as email clients, some mobile apps and privacy-focused browsers.

Token authentication

For files that should not be shareable at all, Bunny token authentication adds token and expires parameters to URLs. Your application signs each URL with a security key, the path and an expiry time, and Bunny checks the signature on every request.

  • Basic: MD5 hashing, with optional IP validation.
  • Advanced: SHA256, with options such as geo-restrictions, directory-level tokens and speed limits.

Token authentication requires code that generates signed URLs. OffloadX does not create signed URLs, so for tokens you would need a separate tool or custom code; referrer rules work with any plugin. Our Bunny Storage WordPress guide covers the pull zone setup OffloadX needs.

Amazon CloudFront and AWS WAF

If your media is on Amazon S3 behind CloudFront, you have three tools, from light to strict.

prevent hotlinking WordPress: Cost of 1 TB of hotlinked traffic
Cost of 1 TB of hotlinked traffic

1. S3 bucket policy with aws:Referer

AWS documents a bucket policy that only allows s3:GetObject when aws:Referer matches your site. The S3 bucket policy examples warn that anyone can send any referer value, so this should only discourage embedding on other sites, not protect private data. It also only works if visitors reach the bucket directly rather than through CloudFront.

2. AWS WAF on the distribution

Attach an AWS WAF web ACL to the CloudFront distribution, with a rule that blocks media requests whose Referer header is present and does not contain your domain. AWS WAF pricing lists $5 per web ACL per month, $1 per rule group or managed rule group per month, and $0.60 per million requests. CloudFront’s flat-rate plans also bundle WAF, per the CloudFront pricing page.

3. Signed URLs or signed cookies

For paid or private content, CloudFront signed URLs and cookies restrict access to selected users, and AWS recommends also blocking direct access to the S3 origin. Like Bunny tokens, this needs code to sign URLs.

For the S3 side of an offload setup, see offloading WordPress media to Amazon S3.

MethodStops casual embeddingStops determined copyingNeeds code
Bucket policy with aws:RefererYes, direct S3 onlyNoNo
AWS WAF referer ruleYesNoNo
Signed URLs or cookiesYesYes, until the URL expiresYes

Caveats: Blank Referrers, Feeds, Social and Google

Most support tickets after adding hotlink protection come from blocking something legitimate. Check these before you switch rules on.

Blank referrers

Always allow blank referers unless you have a strong reason. They come from direct visits, bookmarks, email clients, apps, privacy extensions and sites that send no-referrer. Both Cloudflare’s toggle and Bunny’s default allow them for this reason.

RSS and feed readers

Feed readers show your posts, with images, on their own domain. Their requests carry the reader’s referer or none, so strict rules can leave subscribers with broken images. Either allow the readers your audience uses or accept that some feed images will not show.

Social previews

When someone shares your link, the platform’s crawler fetches your og:image. Crawlers generally fetch the image themselves rather than from a page on your site, so check that your rules do not block them. Test a share on each network you care about after changing rules.

Google Images

Google’s image SEO documentation explains that Google Images can inline-link your images. If you opt out by returning a 200 or 204 response with no content to requests referred from Google, Google says it will still crawl the page and show a thumbnail generated at crawl time. Returning a 403 to Google referers is not what the guidance describes, so allow Google in your rules unless you have deliberately chosen to opt out.

Other things you might block by accident

  • Your own staging site, subdomains or multisite domains.
  • Translation and web cache services.
  • Newsletter tools that show your images in emails.
  • Partners or resellers you have allowed to use product photos.
  • Your WordPress admin, if it runs on a different hostname.

Which Method Should You Use?

The best way to prevent hotlinking WordPress files is to enforce the rule where the files are actually served.

Where media is served fromBest method
Your server on Apache, no CDN.htaccess referer rules
Your server on nginx, no CDNvalid_referers
Your server behind CloudflareHotlink Protection toggle, plus a custom rule for WebP, AVIF and video
Cloudflare R2 on a custom domainCloudflare custom rule on that hostname
Bunny Storage via a pull zoneAllowed referrers; token authentication for private files
Amazon S3 with CloudFrontAWS WAF referer rule; signed URLs for private files
Paid downloads or coursesSigned or token URLs, not referer rules

If you offload media with OffloadX, set protection on the bucket’s delivery domain or CDN, because that is where requests arrive. OffloadX Starter and above include a CDN safety checker, and every plan works with R2, S3, Wasabi, Google Cloud, DigitalOcean Spaces, Bunny Storage and other S3-compatible services.

Testing Your Rules

Test with curl so you can control the referer exactly. Replace the URL with one of your image URLs.

TestCommandExpected
Your own sitecurl -I -e "https://www.example.com/" URL200
Another sitecurl -I -e "https://other-site.test/" URL403
Blank referercurl -I URL200
Googlecurl -I -e "https://www.google.com/" URL200, if allowed
Each file typeRepeat with .webp, .avif and .mp4 URLsSame results

After the curl tests

  1. Load your home page, a post and a product page in a private window.
  2. Check the browser console for blocked images.
  3. Share a post on one social network and check the preview.
  4. Watch CDN analytics for a few days for unexpected 403s.
  5. Purge the CDN cache if a 403 response was cached during testing.

Frequently Asked Questions

Does hotlink protection hurt SEO?

Not if you allow search engines. Allow Google referers and blank referers, and your images stay eligible for image search.

Can a plugin prevent hotlinking WordPress images?

Some security plugins write .htaccess rules for you. That only helps while images are served by Apache on your server; offloaded or CDN-cached media needs rules at the CDN.

Why does Cloudflare Hotlink Protection not block my WebP images?

Cloudflare documents it as covering gif, ico, jpg, jpeg and png only. Use a WAF custom rule for WebP, AVIF, SVG, video and documents.

Should I block empty referers?

Usually not. Bunny and Cloudflare both allow them by default because email clients, apps and privacy tools send none. Blocking them breaks more for real visitors than it stops.

Is referer checking secure?

No. Referers are easy to fake, as nginx and AWS both warn. They stop other sites embedding your files; use signed or token URLs for anything that must stay private.

Do I need hotlink protection on Cloudflare R2?

For cost, rarely, because R2 egress is free. You may still want it to stop other sites using your images or video, which needs a custom domain and a WAF custom rule.

Can I let some sites hotlink my images?

Yes. Add them to your allowed referrers, exempt them in a Cloudflare rule, or put shared files in a hotlink-ok folder if you use Cloudflare’s toggle.

Why did my own images break after adding rules?

Usually a missing hostname, such as the bare domain, www or a staging site, or a cached 403 at the CDN. Add the hostname and purge the cache.

Conclusion

To prevent hotlinking WordPress media, block unknown referers where your files are actually served: .htaccess or nginx on your own server, and Cloudflare, Bunny or AWS WAF rules once media is offloaded or cached. Allow blank referers, search engines and your own domains, and use signed or token URLs for anything that must stay private.

See OffloadX Plans →

Bandwidth prices, Cloudflare custom rule limits and AWS WAF pricing were checked September 2026 on vendor pages. Rule examples are starting points; test them on staging before using them on a live site.