.net项目防止盗链的几种实现方案

项目背景

甲方本地化上线了我们系统之后,进行安全漏洞扫描

发现了一个问题:

我们的附件路径 直接通过站点 访问的 ,在未授权的模式下,可以直接随意替换路径里的文件内容,通过浏览器拼接链接的方式打开系统里的一些附件和图片内容

因为系统内部 站点 呈现附件 也都是通过这个方式拼接呈现的。

 

 

快速调整方案一:用了 授权认证 的方式,控制附件图片的访问 

需要在.net 代码的webconfig 文件里 添加 用户控制,这里deny 拒绝所有用户

  <!--开启上传目录权限用户访问-->
  <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>

  同时webcofig 里的 module 节点里 添加以下代码,以保证上面的文件访问规则,能正常执行。

<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" />

  

通过上述两段配置,可以快速实现 用户未登录的情况下,无法直接通过图片路径打卡图片,防止恶意获取信息。

方案一缺点:但其实这个不是最完善的方式,对于已经登录的用户,还是可以通过拼接链接,修改链接中的参数,直接渲染其他图片。

 

加强方案二:我们可以通过添加httphandler  对所有请求的 Referer 来源进行判断来 控制访问权限

      可以结合方案一使用

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[RefererKey];
        // 如果 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; }
    }
} 

在 web.config 中添加以下配置,将所有请求指向该处理程序

<configuration>
    <system.web>
        <httpHandlers>
            <add verb="*" path="*" type="AntiLeechHandler" />
        </httpHandlers>
    </system.web>
</configuration>

  

也可以自定义 HTTP 模块判断Referer

 

自定义 HTTP 模块可以在请求处理管道的早期介入,进行更复杂的逻辑判断,如验证签名、检查时间戳等,以确保请求的合法性和安全性。示例代码如下

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[RefererKey];
            // 如果 Referer 为空或者不匹配允许的站点,则进行处理
            if (string.IsNullOrEmpty(referer) || !referer.StartsWith(AllowedReferer))
            {
                context.Response.Clear();
                context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound; // 设置状态码为 404
                context.Response.End();
            }
        };
    }
}

  在 web.config 中注册自定义模块

<configuration>
    <system.web>
        <httpModules>
            <add name="WebHotlinkProtectionModule" type="WebHotlinkProtectionModule" />
        </httpModules>
    </system.web>
</configuration>

  

方案二缺点:因为可能存在 Referer  伪造,所以还是可能存在风险

 

 

加强方案三:对链接添加token ,通过失效控制和token 解析 防止盗链

        可以结合方案一和方案二使用

       方案三缺点:这个逻辑 目前考虑下来,可能对现有系统的调整会比较大,固还没有尝试。

 

来源链接:https://www.cnblogs.com/jayblog/p/18852197

© 版权声明
THE END
支持一下吧
点赞13 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容