PyPI发布GitHub Action存在可注入的表达式扩展漏洞剖析

本文详细分析了PyPI发布GitHub Action中的一个低危漏洞。该漏洞源于在`set-repo-and-ref`步骤中使用了可能被攻击者控制的上下文进行表达式扩展,在特定条件下可能导致命令注入。文章涵盖了漏洞详情、影响范围和修复方案。

漏洞概述

GHSA ID: GHSA-vxmw-7h4f-hqxh

严重性等级:

发布日期: 2025年9月4日

受影响版本: < 1.13.0

修复版本: 1.13.0

漏洞详情

gh-action-pypi-publish是一个GitHub Actions复合操作,用于向PyPI发布Python包。在该操作的set-repo-and-ref步骤中,存在潜在的表达式扩展注入漏洞。

漏洞代码分析

问题出现在以下代码段中(摘自action.yml):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
- name: Set repo and ref from which to run Docker container action
  id: set-repo-and-ref
  run: |
    # Set repo and ref from which to run Docker container action
    # to handle cases in which `github.action_` context is not set

    REF=${{ env.ACTION_REF || env.PR_REF || github.ref_name }}
    REPO=${{ env.ACTION_REPO || env.PR_REPO || github.repository }}
    REPO_ID=${{ env.PR_REPO_ID || github.repository_id }}
    echo "ref=$REF" >>"$GITHUB_OUTPUT"
    echo "repo=$REPO" >>"$GITHUB_OUTPUT"
    echo "repo-id=$REPO_ID" >>"$GITHUB_OUTPUT"
  shell: bash
  env:
    ACTION_REF: ${{ github.action_ref }}
    ACTION_REPO: ${{ github.action_repository }}
    PR_REF: ${{ github.event.pull_request.head.ref }}
    PR_REPO: ${{ github.event.pull_request.head.repo.full_name }}
    PR_REPO_ID: ${{ github.event.pull_request.base.repo.id }}

漏洞原理

  1. 表达式扩展机制

    • 代码使用了GitHub Actions的表达式语法${{ ... }},而不是Shell变量扩展语法${...}
    • ${{ ... }}表达式在执行Shell命令之前由GitHub Actions运行器进行求值
  2. 注入点分析

    • REF=${{ env.ACTION_REF || env.PR_REF || github.ref_name }}这行代码中
    • 如果env.ACTION_REFenv.PR_REF都为空字符串,表达式将回退到github.ref_name
    • github.ref_name可能包含攻击者控制的输入(如分支名或标签名)
  3. 攻击示例: 假设攻击者能够设置一个分支名为:

    1
    
    innocent;cat${IFS}/etc/passwd
    

    经过表达式扩展后,代码将变为:

    1
    
    REF=innocent;cat${IFS}/etc/passwd
    

    这会将REF变量设置为innocent,然后执行攻击者的代码(cat /etc/passwd

技术细节

  • 绕过Shell引号规则:由于使用${{ ... }}进行扩展发生在Shell解释之前,因此可以绕过正常的Shell引号机制
  • 条件限制:该漏洞仅在特定条件下可被利用:
    • env.ACTION_REF必须为空(正常情况下应始终优先)
    • 工作流必须使用允许攻击者控制github.ref_name的触发器

影响范围

该漏洞的影响非常低,原因如下:

  1. 正常操作中难以触发

    • env.ACTION_REF在大多数情况下都会优先,阻止回退到github.ref_name
    • 在常见的配置中(如使用pull_requestreleasepush: tags事件)不易受到攻击
  2. 需要特定条件

    • 只有在使用特定类型的事件触发器,且ACTION_REFPR_REF都为空时,漏洞才可能被利用

修复方案

版本1.13.0中已修复此漏洞。修复方法包括:

  • 改进了表达式扩展的处理方式
  • 添加了输入验证和安全措施

参考信息

CVSS评分

整体评分: 0.0/10 (低严重性)

CVSS v3.1向量: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N

基本指标:

  • 攻击向量:网络
  • 攻击复杂度:低
  • 所需权限:无
  • 用户交互:无
  • 范围:未改变
  • 机密性影响:无
  • 完整性影响:无
  • 可用性影响:无

CWE分类

CWE-77: 命令中使用的特殊元素的不当中和(命令注入)

  • 产品使用来自上游组件的外部影响输入来构造命令的全部或部分,但在将命令发送到下游组件时,没有中和或错误地中和了可能修改预期命令的特殊元素。

致谢

该漏洞由 woodruffw 报告。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计