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

View File

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

View File

@ -22,8 +22,9 @@
"zhuyuan_bucket": {
"core": "zy-core-bucket-1317346199",
"region": "ap-singapore",
"inbox_prefix": "inbox/{persona_id}/{date}/",
"permission": "仅限写入inbox目录不可读取其他内容"
"inbox_prefix": "inbox/{persona_id}/",
"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,保留兼容)",
"protocol": "HLDP v2.0",

View File

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

View File

@ -56,7 +56,12 @@ exports.main_handler = async (event, context) => {
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 {
const result = await triggerGitHubWorkflow(owner, repo, githubToken, objectKey);
@ -88,7 +93,7 @@ function triggerGitHubWorkflow(owner, repo, token, cosObjectKey) {
method: 'POST',
headers: {
'User-Agent': 'HoloLake-SCF-Trigger/2.0',
'Authorization': `Bearer ${token}`,
'Authorization': `token ${token}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)

Binary file not shown.