Bash 脚本把未转义的参数和 Azure 响应拼入 Python 程序
原文依据:4 处脚本从第四个位置参数取得 REGION,并把 `$REGION` 直接展开到 `python3 -c` 的单引号 f-string 中;它还把完整的 `$USAGES_JSON` 展开进三单引号 Python 字符串。两者都不是作为数据安全传给 Python。含有引号和 Python 语法的特制区域参数,或异常/被操纵的 CLI JSON 字符串,可以结束字符串并改变要执行的 Python 代码。
成功利用时,运行检查脚本会以当前用户身份执行额外的本地 Python 代码,可读取该用户可访问的文件和凭据,或修改文件。普通 Azure 区域名和正常响应不会自行触发此问题。
风险成立,但候选描述有一处错误:REGION 来自第二个参数,不是第四个。脚本将 Azure 返回的完整 JSON 和用户提供的 REGION 直接展开进 `python3 -c` 源码。若其中包含能闭合 Python 字符串的内容,可能改变本机执行的 Python 代码。用户可要求作者通过环境变量、stdin 或参数传递纯数据,并限制 region 为 Azure 区域名格式。
RESOURCE_PROVIDER="${1:?Usage: $0 <resource-provider> <region> [resource-name] [subscription-id]}"REGION="${2:?Usage: $0 <resource-provider> <region> [resource-name] [subscription-id]}"RESOURCE_NAME="${3:-}"SUBSCRIPTION_ID="${4:-}"查看另外 3 个位置
echo "$QUOTAS_JSON" | python3 -c "import json, sysquotas = json.load(sys.stdin)usages = json.loads('''$USAGES_JSON''')usage_lookup = {}for u in usages: usage_lookup[u['name']] = u.get('properties', {}).get('usages', {}).get('value', 0)for q in quotas: name = q['name'] limit = q.get('properties', {}).get('limit', {}).get('value', 0) used = usage_lookup.get(name, 0) avail = limit - used print(f'{name:<40} $REGION{\"\":<4} {limit:<10} {used:<10} {avail:<10}')"fi QUOTAS_JSON=$(az quota list --scope "$SCOPE" -o json 2>/dev/null) USAGES_JSON=$(az quota usage list --scope "$SCOPE" -o json 2>/dev/null) printf "%-40s %-10s %-10s %-10s %-10s\n" "Resource" "Region" "Limit" "Usage" "Available" printf "%-40s %-10s %-10s %-10s %-10s\n" "--------" "------" "-----" "-----" "---------" echo "$QUOTAS_JSON" | python3 -c "import json, sysquotas = json.load(sys.stdin)usages = json.loads('''$USAGES_JSON''')for q in quotas: name = q['name'] limit = q.get('properties', {}).get('limit', {}).get('value', 0) used = usage_lookup.get(name, 0) avail = limit - used print(f'{name:<40} $REGION{\"\":<4} {limit:<10} {used:<10} {avail:<10}')"fi