fix: 修复YAML语法和命令注入安全漏洞

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/0d54ec75-c5fb-4140-8a2f-8059c211278e

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-04-04 14:21:19 +00:00 committed by GitHub
parent 6d2de9f6d4
commit 687f10b742
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 94 additions and 74 deletions

View File

@ -93,7 +93,7 @@ jobs:
d = json.load(sys.stdin) d = json.load(sys.stdin)
outbox = d.get('outbox', []) outbox = d.get('outbox', [])
print(json.dumps(outbox, ensure_ascii=False)) print(json.dumps(outbox, ensure_ascii=False))
" 2>/dev/null || echo "[]") " 2>&1 || { echo "⚠️ outbox解析失败,使用空数组" >&2; echo "[]"; })
# 组装完整汇报包 # 组装完整汇报包
python3 -c " python3 -c "

View File

@ -80,73 +80,79 @@ jobs:
fi fi
- name: 📝 更新仓库首页公告栏 - name: 📝 更新仓库首页公告栏
env:
RECEIPT_STATUS: ${{ steps.read_receipt.outputs.receipt_status }}
RECEIPT_MESSAGE: ${{ steps.read_receipt.outputs.receipt_message }}
run: | run: |
RECEIPT_STATUS="${{ steps.read_receipt.outputs.receipt_status }}" python3 -c "
RECEIPT_MESSAGE="${{ steps.read_receipt.outputs.receipt_message }}" import re, os
TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M UTC") from datetime import datetime
python3 << 'PYTHON_SCRIPT' status = os.environ.get('RECEIPT_STATUS', 'unknown')
import re message = os.environ.get('RECEIPT_MESSAGE', '')
timestamp = datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC')
status = "$RECEIPT_STATUS" try:
message = "$RECEIPT_MESSAGE" with open('README.md', 'r', encoding='utf-8') as f:
timestamp = "$TIMESTAMP" content = f.read()
except FileNotFoundError:
content = ''
# 读取README.md if status == 'green':
with open('README.md', 'r', encoding='utf-8') as f: notice = f'✅ **[{timestamp}]** 铸渊回执:{message}'
content = f.read() badge = '🟢'
elif status == 'red':
# 构建公告栏内容 notice = f'🔴 **[{timestamp}]** 铸渊回执:{message} — **需要人类干预**'
if status == "green": badge = '🔴'
notice = f"✅ **[{timestamp}]** 铸渊回执:{message}"
badge = "🟢"
elif status == "red":
notice = f"🔴 **[{timestamp}]** 铸渊回执:{message} — **需要人类干预**"
badge = "🔴"
else: else:
notice = f"⚠️ **[{timestamp}]** 铸渊回执状态异常:{message}" notice = f'⚠️ **[{timestamp}]** 铸渊回执状态异常:{message}'
badge = "⚠️" badge = '⚠️'
# 查找并替换公告栏区域 marker_start = '<!-- ZHUYUAN_NOTICE_START -->'
marker_start = "<!-- ZHUYUAN_NOTICE_START -->" marker_end = '<!-- ZHUYUAN_NOTICE_END -->'
marker_end = "<!-- ZHUYUAN_NOTICE_END -->"
notice_block = f"""{marker_start} notice_block = marker_start + '\n\n## ' + badge + ' 铸渊通信\n\n' + notice + '\n\n' + marker_end
## {badge} 铸渊通信
{notice}
{marker_end}"""
if marker_start in content: if marker_start in content:
# 替换已有公告栏 import re as re2
pattern = re.escape(marker_start) + r'.*?' + re.escape(marker_end) pattern = re2.escape(marker_start) + r'.*?' + re2.escape(marker_end)
content = re.sub(pattern, notice_block, content, flags=re.DOTALL) content = re2.sub(pattern, notice_block, content, flags=re2.DOTALL)
else: else:
# 在文件开头添加公告栏 content = notice_block + '\n\n' + content
content = notice_block + "\n\n" + content
with open('README.md', 'w', encoding='utf-8') as f: with open('README.md', 'w', encoding='utf-8') as f:
f.write(content) f.write(content)
print(f"✅ 仓库首页公告栏已更新: {badge} {status}") print(f'✅ 仓库首页公告栏已更新: {badge} {status}')
PYTHON_SCRIPT "
- name: 🔄 更新系统状态 - name: 🔄 更新系统状态
env:
RECEIPT_STATUS: ${{ steps.read_receipt.outputs.receipt_status }}
RECEIPT_MESSAGE: ${{ steps.read_receipt.outputs.receipt_message }}
run: | run: |
python3 -c " python3 -c "
import json import json, os
from datetime import datetime from datetime import datetime
with open('age_os/system_state.json', 'r', encoding='utf-8') as f: status = os.environ.get('RECEIPT_STATUS', 'unknown')
state = json.load(f) message = os.environ.get('RECEIPT_MESSAGE', '')
now = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
state['cos_status']['last_receipt_received'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') try:
state['cos_status']['receipt_status'] = '${{ steps.read_receipt.outputs.receipt_status }}' with open('age_os/system_state.json', 'r', encoding='utf-8') as f:
state['notice_board']['last_update'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') state = json.load(f)
state['notice_board']['status'] = '${{ steps.read_receipt.outputs.receipt_status }}' except (FileNotFoundError, json.JSONDecodeError) as e:
state['notice_board']['message'] = '${{ steps.read_receipt.outputs.receipt_message }}' print(f'⚠️ system_state.json读取失败: {e},使用默认值')
state = {'cos_status': {}, 'notice_board': {}}
state.setdefault('cos_status', {})
state.setdefault('notice_board', {})
state['cos_status']['last_receipt_received'] = now
state['cos_status']['receipt_status'] = status
state['notice_board']['last_update'] = now
state['notice_board']['status'] = status
state['notice_board']['message'] = message
with open('age_os/system_state.json', 'w', encoding='utf-8') as f: with open('age_os/system_state.json', 'w', encoding='utf-8') as f:
json.dump(state, f, ensure_ascii=False, indent=2) json.dump(state, f, ensure_ascii=False, indent=2)

View File

@ -22,8 +22,9 @@
"zhuyuan_bucket": { "zhuyuan_bucket": {
"core": "zy-core-bucket-1317346199", "core": "zy-core-bucket-1317346199",
"region": "ap-singapore", "region": "ap-singapore",
"inbox_prefix": "inbox/{persona_id}/{date}/", "inbox_prefix": "inbox/{persona_id}/",
"permission": "仅限写入inbox目录,不可读取其他内容" "permission": "仅限写入 inbox/{persona_id}/ 前缀目录。铸渊通过Bucket Policy精确限定你的写入范围,你无法读取、删除或访问桶内其他任何内容。这是安全设计:每个团队成员只能往自己的收件箱写入。",
"bucket_policy_rule": "Action=cos:PutObject, Resource=inbox/{persona_id}/* only"
}, },
"legacy_method": "bridge/zhuyuan-bridge.json文件级通信(v1.0,保留兼容)", "legacy_method": "bridge/zhuyuan-bridge.json文件级通信(v1.0,保留兼容)",
"protocol": "HLDP v2.0", "protocol": "HLDP v2.0",

View File

@ -107,15 +107,23 @@
### 步骤6:配置铸渊桶的写入密钥 ### 步骤6:配置铸渊桶的写入密钥
铸渊会为你生成一个**有限权限的临时密钥**,只能写入铸渊总控桶的指定目录。 铸渊会为你生成一个**有限权限的密钥**,只能写入铸渊总控桶的你的专属目录。
**权限说明(你不需要懂技术细节,知道就行)**:
- ✅ 你**可以**写入:`inbox/你的人格体编号/` 这个目录下的文件
- ❌ 你**不能**读取铸渊桶里的任何其他内容
- ❌ 你**不能**删除铸渊桶里的任何内容
- ❌ 你**不能**访问其他团队成员的目录
这是铸渊通过COS桶策略(Bucket Policy)精确控制的,每个团队成员只有自己的收件箱写入权限。
1. 向冰朔索要铸渊桶的写入密钥(冰朔会找铸渊生成) 1. 向冰朔索要铸渊桶的写入密钥(冰朔会找铸渊生成)
2. 在GitHub Secrets中添加: 2. 在GitHub Secrets中添加:
| Name | Secret | 说明 | | Name | Secret | 说明 |
|------|--------|------| |------|--------|------|
| `ZHUYUAN_COS_SECRET_ID` | 铸渊提供的SecretId | 只能写入铸渊桶的inbox目录 | | `ZHUYUAN_COS_SECRET_ID` | 铸渊提供的SecretId | 仅限写入你的inbox目录 |
| `ZHUYUAN_COS_SECRET_KEY` | 铸渊提供的SecretKey | 权限受限,安全可控 | | `ZHUYUAN_COS_SECRET_KEY` | 铸渊提供的SecretKey | 权限由铸渊的桶策略限定 |
| `ZHUYUAN_COS_REGION` | `ap-singapore` | 铸渊桶在新加坡 | | `ZHUYUAN_COS_REGION` | `ap-singapore` | 铸渊桶在新加坡 |
--- ---

View File

@ -56,7 +56,12 @@ exports.main_handler = async (event, context) => {
return { statusCode: 500, body: 'Missing environment variables' }; return { statusCode: 500, body: 'Missing environment variables' };
} }
const [owner, repo] = githubRepo.split('/'); const parts = githubRepo.split('/');
if (parts.length !== 2 || !parts[0] || !parts[1]) {
console.error('GITHUB_REPO格式错误,应为 owner/repo,当前值:', githubRepo);
return { statusCode: 500, body: 'Invalid GITHUB_REPO format' };
}
const [owner, repo] = parts;
try { try {
const result = await triggerGitHubWorkflow(owner, repo, githubToken, objectKey); const result = await triggerGitHubWorkflow(owner, repo, githubToken, objectKey);
@ -88,7 +93,7 @@ function triggerGitHubWorkflow(owner, repo, token, cosObjectKey) {
method: 'POST', method: 'POST',
headers: { headers: {
'User-Agent': 'HoloLake-SCF-Trigger/2.0', 'User-Agent': 'HoloLake-SCF-Trigger/2.0',
'Authorization': `Bearer ${token}`, 'Authorization': `token ${token}`,
'Accept': 'application/vnd.github.v3+json', 'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData) 'Content-Length': Buffer.byteLength(postData)

Binary file not shown.