.net项目防止盗链的几种实现方案
<p>项目背景</p><p>甲方本地化上线了我们系统之后,进行安全漏洞扫描</p>
<p>发现了一个问题:</p>
<p><span style="color: rgba(255, 0, 0, 1)">我们的附件路径 直接通过站点 访问的 ,在未授权的模式下,可以直接随意替换路径里的文件内容,通过浏览器拼接链接的方式打开系统里的一些附件和图片内容</span></p>
<p>因为系统内部 站点 呈现附件 也都是通过这个方式拼接呈现的。</p>
<p> </p>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>快速调整方案一</strong>:用了 授权认证 的方式,控制附件图片的访问 </span></p>
<p>需要在.net 代码的webconfig 文件里 添加 用户控制,这里deny 拒绝所有用户</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;"><!--开启上传目录权限用户访问-->
<location path="Upload">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<!--移除文件缓存-->
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<!--取消权偏好设置文件的限访问-->
<location path="Upload/BackgroundImg">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
<!--取消权偏好设置文件的限访问-->
<location path="Upload/LogoIcon">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
</pre>
</div>
<p> 同时webcofig 里的 module 节点里 添加以下代码,以保证上面的文件访问规则,能正常执行。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;"><add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<remove name="DefaultAuthentication" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</pre>
</div>
<p> </p>
<p>通过上述两段配置,可以快速实现 用户未登录的情况下,无法直接通过图片路径打卡图片,防止恶意获取信息。</p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>方案一缺点:</strong>但其实这个不是最完善的方式,对于已经登录的用户,还是可以通过拼接链接,修改链接中的参数,直接渲染其他图片。</span></p>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>加强方案二</strong>:我们可以通过<strong>添加httphandler </strong> 对所有请求的 Referer 来源进行判断来 控制访问权限</span></p>
<p> 可以结合方案一使用</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">using System;
using System.Web;
public class AntiLeechHandler : IHttpHandler
{
private const string RefererKey = "Referer";
private const string AllowedReferer = "http://www.yoursite.com";
public void Dispose()
{
}
public void ProcessRequest(HttpContext context)
{
string referer = context.Request.Headers;
// 如果 Referer 为空或者不匹配允许的站点,则进行处理
if (string.IsNullOrEmpty(referer) || !referer.StartsWith(AllowedReferer))
{
context.Response.Clear();
context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; // 设置状态码为 404
context.Response.End();
}
else
{
// 合法请求,继续处理
string filePath = context.Server.MapPath(context.Request.Path);
if (System.IO.File.Exists(filePath))
{
context.Response.ContentType = GetContentType(filePath);
context.Response.WriteFile(filePath);
}
else
{
context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
}
}
}
private string GetContentType(string filePath)
{
string extension = System.IO.Path.GetExtension(filePath).ToLower();
switch (extension)
{
case ".jpg":
case ".jpeg":
return "image/jpeg";
case ".png":
return "image/png";
case ".gif":
return "image/gif";
case ".pdf":
return "application/pdf";
// 可根据需要添加更多文件类型的 MIME 类型
default:
return "application/octet-stream";
}
}
public bool IsReusable
{
get { return false; }
}
} </pre>
</div>
<p>在 <code>web.config</code> 中添加以下配置,将所有请求指向该处理程序</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;"><configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*" type="AntiLeechHandler" />
</httpHandlers>
</system.web>
</configuration>
</pre>
</div>
<p> </p>
<p><strong><span style="color: rgba(255, 0, 0, 1)">也可以自定义 HTTP </span>模块判断</strong>Referer</p>
<p> </p>
<p>自定义 HTTP 模块可以在请求处理管道的早期介入,进行更复杂的逻辑判断,如验证签名、检查时间戳等,以确保请求的合法性和安全性。示例代码如下</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">using System;
using System.Web;
public class WebHotlinkProtectionModule : IHttpModule
{
private const string RefererKey = "Referer";
private const string AllowedReferer = "http://www.yoursite.com";
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += (sender, e) =>
{
string referer = context.Request.Headers;
// 如果 Referer 为空或者不匹配允许的站点,则进行处理
if (string.IsNullOrEmpty(referer) || !referer.StartsWith(AllowedReferer))
{
context.Response.Clear();
context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; // 设置状态码为 404
context.Response.End();
}
};
}
}
</pre>
</div>
<p> 在 <code>web.config</code> 中注册自定义模块</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;"><configuration>
<system.web>
<httpModules>
<add name="WebHotlinkProtectionModule" type="WebHotlinkProtectionModule" />
</httpModules>
</system.web>
</configuration>
</pre>
</div>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>方案二缺点</strong>:因为可能存在 Referer 伪造,所以还是可能存在风险</span></p>
<p> </p>
<p> </p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>加强方案三</strong>:对链接添加token ,通过失效控制和token 解析 防止盗链</span></p>
<p> 可以结合方案一和方案二使用</p>
<p><span style="color: rgba(255, 0, 0, 1)"> <strong>方案三缺点:</strong>这个逻辑 目前考虑下来,可能对现有系统的调整会比较大,固还没有尝试。</span></p>
<p> </p><br><br>
来源:https://www.cnblogs.com/jayblog/p/18852197
頁:
[1]