CRLF 漏洞的演变:为何它在今天显得小众

admin 2024年10月11日09:15:01评论32 views字数 3991阅读13分18秒阅读模式

一、CRLF注入概述

1.1 什么是CRLF

CRLF漏洞(Carriage Return Line Feed Injection,回车换行注入)是一种网络安全漏洞,主要出现在Web应用程序中。攻击者利用这一漏洞可以通过在HTTP请求中注入特定的回车符(r)和换行符(n)来操控HTTP响应头。这种攻击的危害包括会话劫持、缓存投毒、跨站点脚本(XSS)等。

1.2 CRLF漏洞危害

CRLF漏洞可能导致多种安全问题,包括:

  1. 会话劫持:通过注入新的Set-Cookie头,攻击者可以窃取用户的会话信息。
  2. 缓存投毒:攻击者可以操纵缓存机制,使得恶意内容被缓存并返回给其他用户。
  3. 跨站点脚本(XSS):如果攻击者能够注入JavaScript代码,通过操控HTTP头,可以在用户的浏览器中执行恶意脚本。

二、CRLF攻击示例与防护措施

CRLF字符在HTTP协议中用于分隔头部字段和头部字段之间的行。在HTTP请求或响应中,每个头部字段都以CRLF结束。因此,如果攻击者能够在头部字段的值中插入CRLF字符,他们就可以创建新的头部字段或破坏现有的头部格式。

2.1 攻击示例

假设一个Web应用程序允许用户输入文件名并将其作为HTTP响应头的一部分返回。如果应用程序没有对用户输入进行适当的验证和清理,攻击者可能会输入如下内容:

filename=test.txt%0D%0ASet-Cookie: test=malicious

在这个例子中,%0D代表回车字符(r),%0A代表换行字符(n)。如果应用程序直接将这个输入放入HTTP响应头中,响应可能看起来像这样:

Content-Disposition: attachment; filename="test.txt"
Set-Cookie: test=malicious

这将导致浏览器接受一个新的Set-Cookie头,从而可能使攻击者能够劫持用户的会话或执行其他恶意行为。

2.2 防护措施

为了防止CRLF漏洞,开发人员可以采用以下措施:

  1. 输入验证:对用户输入进行严格的验证,确保文件名或其他头部字段不包含CRLF字符。
  2. 输入清理:在使用用户输入之前,清理所有无效字符,例如回车和换行。
  3. 使用安全的库:使用经过审查的库和框架,这些库和框架会自动处理HTTP请求和响应的安全性问题。
  4. 编码输出:在输出时对所有动态生成的内容进行适当的编码,以防止恶意代码被执行。

三、为什么CRLF越来越小众?

在早期的 web 开发中,许多应用程序没有对用户输入进行严格的验证,导致了 CRLF 注入和其他类型的注入攻击(如 SQL 注入、XSS 等)的普遍存在。

以CRLF注入为例,其常见于如下场景:

  • HTTP响应头处理:当Web应用程序直接将用户输入用于设置HTTP响应头时,尤其是未经过滤的输入,可能导致CRLF注入。例如,设置Content-DispositionSet-Cookie等响应头时:
func downloadFile(w http.ResponseWriter, r *http.Request) {
    filename := r.FormValue("filename")
    w.Header().Set("Content-Disposition""attachment; filename=""+filename+""")
    // ...
}
  • 重定向与转发:在某些情况下,Web应用程序可能会根据用户输入进行重定向。如果输入未经处理,攻击者可以利用CRLF注入在重定向响应中插入恶意内容。

3.1 响应头处理场景

这里是个文件下载接口,用户传入的文件名没有校验,直接输出,一些常见的白盒工具就会检测到该场景会有CRLF注入漏洞。

import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/api")
public class FileDownloadController {

    @PostMapping("/download")
    public void downloadFile(@RequestParam String filename, HttpServletResponse response) throws IOException {
        // 验证并清理文件名,防止 CRLF 注入
//        String sanitizedFilename = sanitizeFilename(filename);
        System.out.println("Downloading file: " + filename);
        // 设置响应头
        String contentDisposition = String.format("attachment; filename="%s"", filename);

        response.addHeader("Content-Disposition", contentDisposition);
//        response.setContentType("application/octet-stream");

        // 这里可以模拟文件内容的输出,或从实际文件中读取
        response.getWriter().write("This is a dummy file content."); // 模拟文件内容
    }

    // 简单的文件名清理方法
    private String sanitizeFilename(String filename) {
        // 替换 CRLF 字符
        return filename.replaceAll("[\r\n]""");
    }
}
curl -X POST http://127.0.0.1:8000/api/download -d "filename=test.txt%0D%0ASet-Cookie: test=malicious" -i
CRLF 漏洞的演变:为何它在今天显得小众

但是直接请求时,发现CRLF注入并没有生效,Set-Cookie并没有在新的一行,而是一起被当作字符串放在fielname里了。

经过排查,原来在Tomcat 6.0.36 和7.0.29版本之后,就已经做了修复。Tomcat 输出堆栈将响应标头值写入输出流时,它会将 ASCII 控制字符(TAB 除外)和 DEL 转换为空格。

CRLF 漏洞的演变:为何它在今天显得小众

而类似的,Go语言内置的net/http包,也对特殊字符进行了处理。

3.2 重定向与转发场景

在这个重定向示例中,若用户传入的 URL 包含 CRLF 字符,Tomcat 和大多数现代服务器会将这些字符过滤掉,因此即使攻击者尝试注入额外的 HTTP 头部,实际响应中也不会包含这些恶意内容。

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class RedirectController {

    @GetMapping("/redirect")
    public void redirect(@RequestParam String url, HttpServletResponse response) {
        // 直接将 URL 设置到 Location 头中,不进行任何校验
        response.setHeader(HttpHeaders.LOCATION, url);
        response.setStatus(HttpStatus.FOUND.value()); // 302 Found
    }
}
CRLF 漏洞的演变:为何它在今天显得小众

四、结论

虽然 CRLF 注入仍然是一个值得关注的安全问题,但由于现代框架和服务器在这方面的改进,实际攻击的机会和成功率大大降低。因此,这种攻击方式在实际应用中变得相对小众。不过,作为开发者,了解这些安全问题及其历史仍然是非常重要的,因为安全性是任何应用程序设计中的核心部分。

发人员应该始终遵循最佳实践,确保对用户输入进行严格的验证和清理,并定期审查应用程序的安全性。随着网络安全威胁的演变,保持对新漏洞和攻击方式的敏感性是至关重要的。

参考链接:

  • https://stackoverflow.com/questions/63668598/how-can-i-change-this-code-to-be-vulnerable-of-crlf-injection

  • https://owasp.org/www-community/attacks/CRLF_Injection

  • https://tomcat.apache.org/security.html

原文始发于微信公众号(SDL安全):CRLF 漏洞的演变:为何它在今天显得小众

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月11日09:15:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CRLF 漏洞的演变:为何它在今天显得小众https://cn-sec.com/archives/3251938.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息