如何用.htaccess限制网站资源仅允许本站页面加载访问?
问题背景
我们的网站www.horsesandgoats.com将独特字体存储在/includes/fonts/目录下,需要供/includes/内其他文件夹的CSS和JS调用,但近期发现第三方恶意直接采集加载这些字体(例如www.horsesandgoats.com/includes/fonts/mad-font.ttf)。
尝试过的错误规则
曾使用以下.htaccess规则,导致网站出现错误:
<Directory "/includes/fonts"> Order Deny,Allow Deny from all Allow from horsesandgoats.com </Directory>
错误原因:.htaccess本身就是目录级配置文件,无需使用<Directory>标签;且Order Deny,Allow是Apache 2.2的旧语法,若当前服务器为Apache 2.4,会因语法不兼容报错。
待验证的更新规则
考虑在/includes/fonts/目录下使用以下Rewrite规则:
RewriteEngine On RewriteCond %{HTTP_REFERER} . RewriteCond %{HTTP_REFERER} !horsesandgoats\.com [NC] RewriteRule .? - [F]
规则有效性解答
这个规则能基本实现仅本站页面加载的资源调用字体:
当CSS加载字体时,HTTP Referer会携带加载该CSS的HTML页面的URL(即本站域名),因此规则会允许这类合法请求;而第三方直接请求字体时,Referer要么为空,要么是第三方域名,规则会返回403禁止访问。
但该规则存在缺陷:若第三方构造Referer为空的请求,第一个条件%{HTTP_REFERER} .(要求Referer不为空)不满足,规则会跳过,导致这类恶意请求被放行。因此需要优化规则。
最终可行方案
方案1:优化Rewrite规则(推荐)
在/includes/fonts/目录的.htaccess中写入以下规则,覆盖本站Referer、本地测试及Referer为空的合法场景:
RewriteEngine On # 允许来自本站页面的请求(匹配http/https、带/不带www的域名) RewriteCond %{HTTP_REFERER} ^https?://(www\.)?horsesandgoats\.com/ [NC] RewriteRule ^ - [L] # 允许本地测试或服务器内部发起的请求(替换为你的服务器IP) RewriteCond %{HTTP_REFERER} ^$ RewriteCond %{REMOTE_ADDR} ^127\.0\.0\.1$ [OR] RewriteCond %{REMOTE_ADDR} ^192\.168\.1\.100$ RewriteRule ^ - [L] # 拒绝所有其他请求 RewriteRule ^ - [F]
方案2:简洁版Rewrite规则(适合无本地测试需求场景)
RewriteEngine On # 拒绝非本站Referer且Referer不为空的请求 RewriteCond %{HTTP_REFERER} !^https?://(www\.)?horsesandgoats\.com/ [NC] RewriteCond %{HTTP_REFERER} !^$ RewriteRule ^ - [F]
注:此规则会拦截Referer为空的请求,若有本地测试或特殊浏览器场景,建议使用方案1。
方案3:Apache 2.4原生指令(基于IP/主机限制)
若服务器为Apache 2.4,也可使用原生Require指令,但这种方式是限制请求来源IP/主机,而非页面Referer,适合仅允许服务器内部或特定IP访问的场景:
Require all denied Require host horsesandgoats.com Require ip 127.0.0.1 你的服务器IP
内容的提问来源于stack exchange,提问作者Mm-Art-In

