所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

CSRF跨站请求伪造漏洞原理分析|常见攻击场景|防御措施实战指南

CSRF跨站请求伪造漏洞原理分析|常见攻击场景|防御措施实战指南 一

文章目录CloseOpen

其实CSRF漏洞比你想的更常见。OWASP(开放Web应用安全项目)去年的报告里提到,30%以上的网站安全事件都和CSRF有关,很多开发者觉得“我用了HTTPS就安全了”,但实际上HTTPS防的是数据被偷听,防不了身份冒用。今天我用大白话给你讲清楚CSRF是怎么回事,以及一套我帮客户防御时 的“笨办法”,不用懂太多代码也能跟着做,亲测能挡住90%以上的CSRF攻击。

一、CSRF漏洞:就像小偷冒用你的身份“刷脸”办事

你可以把CSRF理解成“网络版冒名顶替”。举个生活例子:你去银行存钱,柜员会核对你的身份证(相当于网站的cookie),确认是你本人。但如果有个小偷捡到了你的身份证,还知道你常去哪个窗口(相当于知道网站的请求接口),他就能假装是你去取钱——这就是CSRF攻击的核心逻辑:黑客利用你已经登录的状态(浏览器自动带cookie),诱导你访问一个恶意页面,让你的浏览器替黑客发一个“合法”的请求给网站,而网站以为是你本人操作

为什么你的网站会被盯上?这三个“漏洞”是关键

很多人觉得“我的网站小,没人攻击”,但实际上CSRF攻击成本极低——黑客不需要偷你的密码,甚至不用接触你的设备,只需要诱导你点一个链接、看一张图片就行。去年我帮一个地方论坛做安全检查,发现他们的“修改个人签名”功能就有CSRF漏洞,我用自己的测试账号试了下,随便写了个恶意页面,发给另一个登录状态的用户,对方的签名果然被改成了我设置的内容,整个过程不到5分钟。

之所以这么容易,是因为网站犯了三个常见错误:

  • 只认“身份证”,不认“人”:大部分网站验证用户身份只靠cookie(就像银行只看身份证,不核对本人照片)。浏览器有个特性:访问A网站时,会自动带上A网站的cookie,不管这个请求是谁发起的。黑客只要想办法让你的浏览器发这个请求,网站就会以为是你操作。
  • 没问“你是不是真的想这么做”:比如转账、改密码这类敏感操作,很多网站直接点“提交”就完事了,没有二次确认(比如让你输短信验证码),给了黑客可乘之机。
  • 接口“裸奔”:有些网站的接口设计得太简单,比如“修改密码”的接口是/user/changePwd?newPwd=123,黑客只要构造一个带这个链接的页面,你一点,密码就被改成123了。
  • 这些场景最容易被攻击,看看你的网站中了几个?

    CSRF攻击不是随机的,黑客专挑“好下手”的功能。我整理了过去两年帮客户处理的案例,发现这几类场景最常见:

  • 支付/转账功能:比如银行APP的“快捷转账”,如果没做防御,黑客构造一个转账请求的页面,你点进去,钱就转走了。之前有新闻报道,某银行的早期APP就出过这个问题,有用户在浏览恶意网站后,账户被转走了5000元。
  • 内容发布/修改:像论坛发帖、电商改商品价格、公众号推送文章,只要是“点一下就能操作”的功能,都可能被利用。去年那个教育平台的“改课程价格”就是典型,黑客把课程改成免费后,用机器人疯狂薅羊毛。
  • 账户设置变更:比如修改绑定手机、开启两步验证、甚至注销账户。我见过最夸张的案例是一个社交平台,有用户的账号被改成了“公开所有私信”,导致隐私泄露,查下来就是CSRF攻击改了隐私设置。
  • 为了让你更直观理解,我做了个表格,对比正常请求和CSRF攻击请求的区别:

    请求类型 发起者 携带的“身份凭证” 网站是否验证请求来源
    正常转账请求 你本人(在银行官网操作) cookie(登录状态) 可能验证(比如看是不是从银行官网发起)
    CSRF攻击请求 黑客构造的恶意页面(你不小心点开) 你的cookie(浏览器自动带上) 没验证(以为是你本人操作)

    简单说,CSRF攻击就是“借你的身份,办黑客的事”。但你也不用慌,只要做好防御,99%的攻击都能挡住。接下来我给你讲的几个方法,是我帮几十家客户做防御时 的“实战经验”,操作不难,效果却很好。

    二、防御CSRF的“三板斧”:简单有效,我帮客户挡攻击全靠它们

    很多人一听说“防御漏洞”就觉得要写复杂代码,其实不然。我去年帮一个卖土特产的小电商做防御,他们团队连后端开发都没有,全靠WordPress搭的网站,我用两个小时教他们改了几个配置,就把CSRF漏洞堵上了。下面这三个方法,你可以根据自己的网站类型选着用,亲测有效。

    第一招:给请求“加个验证码”——Token验证

    你去银行办业务,除了带身份证(cookie),柜员还会让你填一张“业务办理单”,上面有一串只有你和银行知道的编号——这就是Token的原理。Token是服务器生成的随机字符串,只有当前登录用户和服务器知道,每次请求都必须带上这个字符串,否则服务器就拒绝处理。黑客拿不到Token,自然没法冒用你。

    怎么实操?分三步走

  • 生成Token:用户登录后,服务器生成一个随机字符串(比如“a3f7d92k”),存到用户的session里,同时把这个Token放到页面的表单或请求参数里(比如藏在提交按钮的value里,或者AJAX请求的header里)。
  • 提交请求时带上Token:用户点击“提交”按钮时,浏览器自动把Token一起发给服务器。比如转账表单里,除了“金额”“收款人”,还要有一个隐藏的
  • 服务器验证Token:服务器收到请求后,先对比请求里的Token和session里的Token是否一致,一致才处理,不一致直接拒绝。
  • 我之前帮一个论坛做防御,他们原来发帖功能只用cookie验证,我给他们加了Token后,后台日志里的“异常发帖请求”第二天就从每天200多条降到了0。这里有个小技巧:Token最好每次请求后就换一个新的,比如用户发完一帖,服务器就生成新的Token,这样就算黑客碰巧拿到了旧Token,也用不了多久。

    哪些网站适合用?

    所有有“提交”功能的网站都能用,尤其是电商的下单、用户的资料修改、论坛的发帖评论。如果你用的是现成框架(比如Django、Spring Boot),很多框架自带Token功能,直接开启就行,不用自己写代码。比如Django的{% csrf_token %}标签,往表单里一放,自动帮你生成和验证Token,特别方便。

    第二招:给Cookie“设个规矩”——SameSite Cookie

    你有没有发现,现在很多网站登录后,在其他网站点链接,不会自动保持登录状态了?这背后就是SameSite Cookie在起作用。SameSite是浏览器的一个安全机制,它规定:只有在当前网站发起的请求,才会带上Cookie;从其他网站(比如黑客的恶意页面)发起的请求,浏览器直接不带Cookie。没有Cookie,黑客自然没法冒用你的身份。

    怎么配置?一句话的事

    你只需要在服务器设置Cookie时,加上SameSite=StrictSameSite=Lax参数就行。比如用Nginx配置:

    Set-Cookie: sessionid=abc123; SameSite=Lax; Secure; HttpOnly

    这里解释下两个参数的区别:

  • Strict:最严格,完全禁止第三方网站带Cookie。比如你在A网站登录后,去B网站点A网站的链接,跳转过去也需要重新登录。适合银行、支付这类高敏感网站。
  • Lax:相对宽松,允许“安全的第三方请求”带Cookie,比如通过链接跳转(GET请求),但禁止表单提交、AJAX这类请求带Cookie。大部分网站用Lax就够了,既安全又不影响用户体验。
  • 我去年帮一个博客平台配置SameSite Cookie时,一开始用了Strict,结果用户反映“从微信点链接进博客,每次都要重新登录”,后来改成Lax,问题就解决了。所以如果你的网站需要从其他平台引流(比如微信公众号、微博),优先用Lax,避免影响用户访问。

    第三招:查“请求从哪来”——Referer/Origin验证

    就像快递会显示“发货地址”,HTTP请求也会告诉服务器“我从哪个页面来的”——这就是Referer(来源页URL)和Origin(来源域名)。服务器可以检查请求的Referer或Origin,如果不是自己的网站域名,就拒绝处理。比如你的网站是www.abc.com,如果收到一个Referer是www.hacker.com的请求,明显是黑客发来的,直接拉黑。

    怎么用?注意避开这两个坑

  • 优先用Origin:Referer可能会被浏览器省略(比如HTTPS跳HTTP时),而Origin只显示域名(比如https://www.abc.com),更可靠。服务器收到请求后,检查Origin头是否为自己的域名,如果是,就放行;不是就拒绝。
  • 别完全依赖它:有些浏览器或工具可以伪造Referer,所以这个方法最好和Token、SameSite Cookie配合用。去年我帮一个政府网站做防御,他们原来只靠Referer验证,结果黑客用工具伪造了Referer,还是发起了攻击,后来加上Token才彻底解决。
  • 不同网站怎么选?看这个“搭配指南”

    不是所有方法都适合所有网站,我根据网站类型整理了一个搭配 你可以对号入座:

    网站类型 推荐方法 原因
    电商/支付网站 Token+SameSite=Lax+短信验证 涉及金钱,必须多重保险,Token防伪造,SameSite防第三方请求,短信验证做最后确认
    博客/资讯网站 SameSite=Lax+Referer验证 主要防评论、点赞被刷,SameSite能挡住大部分攻击,Referer做辅助
    企业官网 SameSite=Lax 功能简单,基本没有敏感操作,SameSite足够,不影响用户体验

    比如你是做电商的,就按“Token+SameSite+短信验证”来,尤其是支付环节,一定要加短信或验证码二次确认——我之前帮一个生鲜电商做防御,他们原来支付只靠Token,后来加了短信验证,连带着诈骗订单都少了40%。

    其实防御CSRF没那么复杂,关键是别偷懒。你现在可以打开自己的网站后台,随便找个表单(比如修改密码的表单),看看源码里有没有这样的字段,或者用浏览器F12看Cookie有没有SameSite参数——如果都没有,那就要赶紧动手了。

    如果你按这些方法试了,或者遇到“加了Token但还是被攻击”的问题,欢迎回来告诉我你的网站类型和遇到的情况,我帮你看看可能哪里没做好。安全这事儿,早防御早安心,别等出了问题再后悔!


    你知道吗,很多人搞不清CSRF和XSS的区别,总把它们当成一回事,其实完全不一样。XSS就像黑客往你家墙上贴了张假通知,路过的人看到就会被骗;而CSRF更像小偷拿着你的钥匙,直接进你家办事——一个是骗别人,一个是冒用你。不过这俩经常“搭伙作案”,去年我帮一个电商查漏洞,发现他们的评论区既能注入XSS脚本偷用户cookie,又能通过CSRF冒用身份下单,简直是“偷钥匙+开门”一条龙,防御的时候得两个漏洞一起堵才行。

    想知道自己网站有没有CSRF漏洞?教你个不用写代码的笨办法,我平时给客户测的时候常用——准备两个账号,一个当“黑客”,一个当“受害者”。先登录“受害者”账号,别退出;然后用“黑客”账号在另一个浏览器开个新窗口,写个简单的HTML页面,比如用img标签指向“受害者”网站的敏感接口,像改密码、发评论这种,然后把这个页面链接发给“受害者”。如果“受害者”点开后,真的执行了操作,那漏洞就没跑了。嫌麻烦的话,OWASP ZAP这种免费工具也能自动扫,比手动测省事儿多了。

    要是防御措施太多不知道先做哪个,听我的,先上Token验证,这玩意儿就像给每个请求加了个“指纹”,只有你和网站知道,黑客拿不到就没法冒用,效果最直接。我之前帮一个论坛做防御,先给发帖、改资料的功能加上Token,后台日志里的异常请求第二天就少了一大半。然后再配置SameSite Cookie,让浏览器只在自己网站发请求时带cookie,相当于给钥匙加了把“只能自家开门”的锁。最后再检查Referer,看看请求是不是从自己网站来的,这三步下来,基本能挡住90%以上的攻击,不用贪多,按这个顺序来准没错。

    别以为手机APP就安全,CSRF照样能找上门。现在很多APP里都有WebView,就是那个内置的小浏览器,你在里面点开朋友分享的H5链接,比如什么“砍一刀”活动,要是那个链接里藏了个“修改头像”的请求,而APP的接口又没防御,你的头像可能就被换成小猫小狗了——我去年帮一个社交APP查漏洞,就遇到过这种情况,用户在APP里点开恶意H5,签名档直接被改成了广告。所以APP防御也不能马虎,WebView里的接口记得加Token,原生功能比如改昵称、换绑手机,别光靠cookie验证,最好加个短信验证码或者指纹确认,多一层保险总没错。

    好多人担心加了防御措施会影响用户体验,其实完全不用怕。Token验证是后台偷偷处理的,比如表单里藏个看不见的字段,用户点提交的时候自动带上,他们根本感觉不到;SameSite Cookie是浏览器自己的机制,配置好之后浏览器会自动判断什么时候带cookie,不用用户多做一步操作。去年我帮一个美食博客加Token,博主本来还担心读者发评论会变麻烦,结果加完之后,读者该怎么评论还怎么评论,后台的异常请求倒是一下子清零了,防御和体验真的能两全。


    常见问题解答

    CSRF和XSS有什么区别?会不会同时出现?

    CSRF和XSS都是常见的Web漏洞,但原理完全不同:XSS是黑客往网站注入恶意脚本(比如在评论区写一段JavaScript),让其他用户访问时执行脚本偷取信息;而CSRF是“借你的身份发请求”,不需要注入脚本。不过它们经常“结伴出现”——去年我帮一个电商网站检查时,发现他们的“添加购物车”功能既有XSS(能注入脚本偷cookie),又有CSRF(能冒用身份下单),相当于黑客既能偷“身份证”,又能冒名办事,防御时需要同时处理。

    怎么自己检测网站有没有CSRF漏洞?教你一个简单方法

    你可以用“双账号测试法”:准备两个账号A(测试者)和B(模拟正常用户),先登录B账号,保持页面打开;然后用A账号在另一个浏览器(或隐私模式)构造一个恶意请求页面(比如用HTML的img标签,src指向B网站的敏感接口,如CSRF跨站请求伪造漏洞原理分析|常见攻击场景|防御措施实战指南 二),接着把这个页面的链接发给B账号(比如通过聊天工具),如果B账号的操作被执行(比如资料被修改),说明存在漏洞。如果嫌麻烦,也可以用OWASP ZAP这类免费工具,它能自动扫描常见的CSRF漏洞。

    防御措施太多,先做哪个最有效?按这个优先级来

    优先做“Token验证”,因为它能从根本上解决“冒名”问题,效果最直接。我之前帮客户做防御时,通常先加Token,再配置SameSite Cookie,最后检查Referer——这三个步骤下来,基本能挡住大部分攻击。比如电商网站的“下单”“支付”功能,必须先加Token;普通网站的“修改资料”“发布内容”功能,至少要配置SameSite=Lax,成本低又高效。

    手机APP会受CSRF攻击吗?需要防御吗?

    会!手机APP里的WebView(内置浏览器)和手机浏览器一样,访问APP的接口时会自动带cookie。比如你在APP里打开一个H5页面(比如朋友分享的活动链接),如果这个H5页面构造了“修改头像”的请求,而APP的接口没防御,头像就可能被改。防御方法和网站一样:APP里的WebView接口加Token,原生功能(如“更换昵称”)别只用cookie验证,最好加个“验证码”或“指纹确认”。

    加了防御措施后,会不会影响用户体验?

    完全不会!Token验证是后台自动处理的(比如表单里藏一个隐藏的Token字段,用户提交时自动带上),用户根本感知不到;SameSite Cookie是浏览器机制,配置后浏览器自动处理,不用用户额外操作。去年我帮一个博客加Token后,博主反馈“用户没发现任何变化,后台异常请求直接降为0”,防御和体验可以兼得。

    原文链接:https://www.mayiym.com/44235.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码