HTTP CRLF注入攻击

devtools/2024/11/20 20:52:21/
http://www.w3.org/2000/svg" style="display: none;">

HTTP CRLF注入攻击

大家好,今天我们来聊聊一个与网络安全相关的重要话题——CRLF注入(CRLF Injection)。了解这种安全漏洞有助于我们更好地保护我们的应用程序和用户数据。

https://i-blog.csdnimg.cn/direct/1b8458af5ecb442baf48930cdb41c921.jpeg#pic_center" alt="http-security" />

什么是CRLF?

CRLF代表Carriage Return (回车) 和 Line Feed (换行),分别用两个ASCII字符表示:\r(ASCII 13)和\n(ASCII 10)。它们通常一起使用,表示一行文本的结束和新行的开始。CRLF在很多网络协议(如HTTP)和文件格式中都被广泛使用。

CRLF注入简介

CRLF注入是指攻击者通过在输入中插入这些特殊字符(\r\n),改变服务器处理请求或响应的方式,从而实现各种攻击目的的安全漏洞,主要危害如下:

  • 跨站脚本攻击(XSS):通过在HTTP响应头中注入恶意脚本,可以诱使浏览器执行这些脚本。

  • 注入恶意Cookie:如前例,通过重复的Set-Cookie头,攻击者可以施加恶意的Cookie。

  • HTTP响应拆分:引发的响应体劫持或伪造,从而可能实施一些进一步的攻击。

  • 缓存中毒:耍贱骗缓存服务器记录恶意内容,影响后续的合法用户。

注入原理

在Web应用中,许多操作需要处理用户输入并生成HTTP响应头。如果应用程序没有妥善处理用户输入,攻击者可以通过插入CRLF字符,改变HTTP响应头的结构,注入额外的HTTP头或者分割HTTP响应体。

典型攻击场景

会话劫持

通过重复的Set-Cookie头,攻击者可以施加恶意的Cookie,实现会话劫持。假设有一个应用程序需要将用户输入添加到HTTP响应头中:

app.get('/setCookie', (req, res) => {const userInput = req.query.userInput;res.setHeader('Set-Cookie', `name=${userInput}`);res.end('Cookie has been set');
});

如果没有对用户输入进行妥善的验证和过滤,攻击者可以构造如下请求:

http">GET /setCookie?userInput=value%0d%0aSet-Cookie:+isAdmin=true HTTP/1.1
Host: example.com

接收到这个请求后,服务器生成的响应头如下:

http">HTTP/1.1 200 OK
Set-Cookie: name=value
Set-Cookie: isAdmin=true
Content-Length: ...
Content-Type: text/plainCookie has been set

这样,攻击者就成功地通过CRLF注入修改了服务器的HTTP响应头,设置了一个额外的Cookie。

响应拆分

HTTP响应拆分(HTTP Response Splitting)是一种常见的利用CRLF注入的攻击方法。通过这种攻击,攻击者可以在响应头中插入额外的恶意内容,导致服务器发送两个或者更多的HTTP响应。

示例前提

假设我们有一个简单的Web应用,用户可以通过一个查询参数来设置响应头中的一个自定义字段。这个应用的代码可能如下:

const express = require('express');
const app = express();app.get('/welcome', (req, res) => {const userInput = req.query.userInput;res.setHeader('X-Welcome-Message', `Welcome ${userInput}`);res.send('<h1>Welcome to our website!</h1>');
});app.listen(3000, () => {console.log('Server is running on port 3000');
});

在上面的代码中,/welcome 端点会从查询参数 userInput 中读取用户输入,并将其设置为响应头中的 X-Welcome-Message 值。虽然这个代码看起来很好,但如果没有对 userInput 进行适当的验证和过滤,可能会导致HTTP响应拆分攻击。

恶意请求

攻击者可以构造一个恶意URL,通过注入CRLF字符(\r\n)来分割HTTP响应头和体,从而将一个响应拆分成两个响应。假设攻击者发送如下恶意请求:

http">GET /welcome?userInput=value%0d%0aContent-Length:%200%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2014%0d%0a%0d%0a<h1>Pwned!</h1> HTTP/1.1
Host: example.com

我们来解析一下这个URL中的 userInput 值:

value\r\nContent-Length: 0\r\nHTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 14\r\n\r\n<h1>Pwned!</h1>
服务器生成的响应

在这个恶意请求中,userInput 包含了CRLF字符,导致服务器生成的HTTP响应被拆分成两个部分。以下是服务器生成的实际响应:

第一部分(原始响应被截断):
http">HTTP/1.1 200 OK
X-Welcome-Message: Welcome value
Content-Length: 0
第二部分(攻击者注入的响应):
http">HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 14<h1>Pwned!</h1>
具体分析
  1. 第一部分:响应头 X-Welcome-Message 包含了注入的 CRLF 字符,从而将原始响应分成了两个不同的响应部分。
  2. 第二部分:攻击者构造的恶意响应,包含一个新的状态行、响应头和响应体,浏览器将其解释为一个完整的HTTP响应。

防御措施

  1. 对用户输入进行严格验证和过滤:在处理用户输入时,确保所有输入内容安全,并对某些特殊字符进行适当转义或过滤。
  2. 使用框架提供的安全库:大多数现代Web框架都提供了安全库和方法用于防止这种类型的注入攻击。
  3. 设置正确的Content-Type:确保每个HTTP响应都有明确的内容类型设置,减少内容被错误解析或执行的风险。
  4. 正则表达式过滤:通过正则表达式来过滤掉用户输入中的CRLF字符。
  5. 使用第三方库和工具:可以使用一些现成的库或工具来检测和防御CRLF注入攻击,如OWASP提供的安全工具。
代码示例

让我们修改上面的代码,添加防御措施:

const express = require('express');
const app = express();// 过滤用户输入中的CRLF字符
function sanitizeInput(input) {return input.replace(/[\r\n]/g, '');
}app.get('/welcome', (req, res) => {const userInput = sanitizeInput(req.query.userInput);res.setHeader('X-Welcome-Message', `Welcome ${userInput}`);res.send('<h1>Welcome to our website!</h1>');
});app.listen(3000, () => {console.log('Server is running on port 3000');
});

在这个修改后的代码中,我们添加了一个 sanitizeInput 函数,它会去除用户输入中的 \r\n 字符,从而防止HTTP响应拆分攻击。

总结

https://i-blog.csdnimg.cn/direct/451e11d3bfa243b3917c2993f727dbde.png#pic_center" alt="quote-security-http" />

CRLF注入是一种利用Carriage Return\r)和Line Feed\n)字符的注入攻击,常见于HTTP响应拆分攻击。了解和防御这种攻击对维护Web应用的安全至关重要。通过严格验证用户输入,使用安全库,正确设置响应头的内容类型等方法,可以有效防止CRLF注入相关的安全漏洞。希望这次的讲解对大家了解CRLF注入有帮助。如果有任何疑问或进一步的讨论,欢迎留言交流。感谢大家的阅读,我们下次再见!


http://www.ppmy.cn/devtools/135578.html

相关文章

Dubbo源码解析-服务导出(四)

一、服务导出 当我们在某个接口的实现类上加上DubboService后&#xff0c;就表示定义了一个Dubbo服务&#xff0c;应用启动时Dubbo只要扫描到了DubboService&#xff0c;就会解析对应的类&#xff0c;得到服务相关的配置信息&#xff0c;比如&#xff1a; 1. 服务的类型&…

Vue3 动态获取 assets 文件夹图片

我真服了Vue3 这个老六了,一个简单图片src 赋值搞得那么复杂. //item.type 是我遍历类型的类型参数 <img alt"吐槽大会" :src"getAssetUrl(item.type)" /> 基于 Vue2 的Webpack 处理,还不错,可以用/ 这种绝对路径,可以接受,虽然多了个require很不爽…

C++设计模式:工厂方法模式

工厂方法模式是一种创建型设计模式&#xff0c;其核心是将对象的创建延迟到子类中&#xff0c;通过定义一个接口来创建对象&#xff0c;使得子类决定实例化哪一个类。它在需要扩展产品类型时特别有用&#xff0c;能够避免代码的重复和耦合。 工厂方法模式的核心概念 抽象产品&…

【MYSQL】什么是关系型数据库与非关系型数据库?

真正的让你快速理解什么是关系型数据库与非关系型数据库~ 主要是以查询语句&#xff0c;存储结构&#xff0c;拓展 性上的区别。 关系型数据库&#xff08;最经典就是mysql&#xff0c;oracle&#xff09;&#xff1a;它是支持SQL语言&#xff0c;并且关系型数据库大部分都支持…

强化学习数学原理学习(四)

前言 今天是时序差分学习 正文 首先,明确一点,时序差分也是无模型的情况下的强化学习方法,TD学习是蒙特卡洛思想和动态编程&#xff08;DP&#xff09;思想的结合。最基础的时序差分学习估计状态值&#xff0c;而后续提出的Sarsa和Q-learning方法则直接对动作值进行估计。 …

在Linux上如何利用NTP使客户端和服务端的时间同步

对于服务端 一、先在服务端安装相关配置-----yum install chrony -y-----并启动 二、进入chrony的文件里----在第三行修改为阿里云时间服务地址 三、在服务端重启chrony 四、进行测试------chronyc sources -v 五、进入chrony的文件里添加客户端的ip地址---在第26行&#…

关于adb shell登录开发板后terminal显示不完整

现象 今天有个同事跟我说&#xff0c;adb shell 登录开发板后&#xff0c;终端显示不完整&#xff0c;超出边界后就会出现奇怪的问题&#xff0c;比如字符覆盖显示等。如下图所示。 正常情况下应该如下图所示&#xff1a; 很明显&#xff0c;第一张图的显示区域只有完整区域…

爬虫策略——反爬机制

现代网站通常会使用多种反爬手段来限制爬虫访问数据。了解这些机制并针对性地制定绕过策略&#xff0c;是构建高效爬虫的关键。 1. 常见反爬手段 1.1 User-Agent 检查 网站通常会通过检查请求中的 User-Agent 字段&#xff0c;判断访问是否来自真实用户。爬虫默认的请求库&am…