如何重写PyPI镜像代理函数以消除GitHub CodeQL的SSRF告警
如何重写PyPI镜像代理函数以消除GitHub CodeQL的SSRF告警
我明白你遇到的麻烦了——GitHub CodeQL的SSRF告警确实有点严格,但只要我们把输入验证和URL防护做扎实,就能搞定它。问题的核心在于:你当前的代码直接使用用户可控的package参数拼接请求URL,没有足够的校验来确保这个参数不会被用来构造恶意请求(比如路径遍历、跳转到内部服务等)。
下面是经过优化的代码,每一步都针对CodeQL的SSRF检查点做了防护:
import requests import re from urllib.parse import urlparse from fastapi import APIRouter, Response, HTTPException pypi = APIRouter(prefix="/pypi", tags=["bootstrap"]) # 严格匹配PyPI合法包名的正则:仅允许小写字母、数字、连字符、下划线 VALID_PACKAGE_NAME = re.compile(r"^[a-z0-9_\-]+$") # 允许请求的目标域名 ALLOWED_DOMAIN = "pypi.org" @pypi.get("/{package}/", response_class=Response) def get_pypi_package_downloads_list(package: str) -> Response: # 第一步:验证包名格式是否合法 if not VALID_PACKAGE_NAME.match(package): raise HTTPException(status_code=400, detail="Invalid package name format") # 第二步:安全构造目标URL,避免路径遍历风险 base_url = "https://pypi.org/simple/" target_url = f"{base_url}{package}/" # 第三步:解析并验证目标URL的域名 parsed_url = urlparse(target_url) if parsed_url.netloc != ALLOWED_DOMAIN or parsed_url.scheme != "https": raise HTTPException(status_code=403, detail="Unauthorized target URL") try: # 第四步:发起请求时限制重定向,防止被跳转到恶意站点 response = requests.get( target_url, allow_redirects=False, # 禁止重定向,或者自定义重定向钩子只允许PyPI域名 timeout=10 ) # 直接返回PyPI的响应内容和状态码 return Response(content=response.content, status_code=response.status_code, media_type=response.headers.get("Content-Type")) except requests.exceptions.RequestException as e: raise HTTPException(status_code=500, detail=f"Failed to fetch package data: {str(e)}")
关键防护点解释:
- 包名格式校验:用正则严格限制
package参数的字符范围,直接阻断包含路径分隔符(/、../)或其他恶意字符的输入,这是最基础的输入验证。 - URL合法性验证:解析构造后的URL,强制校验域名必须是
pypi.org且协议为HTTPS,彻底杜绝请求被转向其他站点的可能。 - 限制重定向:禁用自动重定向(或者你也可以自定义重定向回调,只允许跳转到PyPI的域名),防止攻击者通过PyPI的重定向规则诱导请求到恶意地址。
- 异常处理:添加请求异常捕获,避免错误信息泄露,同时保证服务稳定性。
这些措施完全覆盖了CodeQL对SSRF防护的要求:既验证了用户输入的合法性,又确保最终请求的目标是可信的,没有被篡改的空间。
备注:内容来源于stack exchange,提问作者TheEponymousProgrammer
相关产品推荐
相关产品推荐

