clawsec-feed by prompt-security/clawsec
npx skills add https://github.com/prompt-security/clawsec --skill clawsec-feed面向 AI 代理的安全通告订阅源监控。订阅社区驱动的威胁情报,及时了解新出现的威胁。
此订阅源每天自动从 NIST 国家漏洞数据库 (NVD) 更新与 OpenClaw、clawdbot 和 Moltbot 相关的 CVE。
由 Prompt Security 开发的开源项目
您可以通过两种方式获取 clawsec-feed:
如果您已经安装了 clawsec-suite,您可能已经拥有此功能!
ClawSec-feed 与 ClawSec 套件捆绑在一起,以提供关键的 CVE 和威胁情报信息。当您安装该套件时,如果您尚未安装此订阅源,它将从捆绑的副本中部署。
优势:
~/.openclaw/skills/clawsec-feed/独立安装 clawsec-feed,无需完整套件。
何时使用独立安装:
优势:
继续阅读以下内容以获取独立安装说明。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
安装步骤:代理应在执行前审阅脚本!
# 获取最新的 clawsec-feed 发布标签
LATEST_TAG=$(curl -sSL https://api.github.com/repos/prompt-security/ClawSec/releases | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name')
# 从最新发布版本下载 SKILL.md
SKILL_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG/SKILL.md"
curl -sSL --fail --show-error "$SKILL_URL"
获取此技能文件后,请继续执行下面的 部署 ClawSec Feed。
安装步骤:
mkdir -p ~/.openclaw/skills/clawsec-feed
# 将本 SKILL.md 文件保存为上述目录中的 SKILL.md
# 使用重试逻辑获取最新发布标签
LATEST_TAG=$(curl -sSL --retry 3 --retry-delay 1 \
https://api.github.com/repos/prompt-security/ClawSec/releases | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name')
BASE_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG"
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills/clawsec-feed}"
TEMP_DIR=$(mktemp -d)
trap "rm -rf '$TEMP_DIR'" EXIT
# 下载 checksums.json(完整性验证必需)
echo "正在下载校验和..."
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$BASE_URL/checksums.json" -o "$TEMP_DIR/checksums.json"; then
echo "错误:无法下载 checksums.json"
exit 1
fi
# 验证 checksums.json 结构
if ! jq -e '.skill and .version and .files' "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then
echo "错误:checksums.json 结构无效"
exit 1
fi
# 主要方式:尝试 .skill 工件
echo "正在尝试 .skill 工件安装..."
if curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$BASE_URL/clawsec-feed.skill" -o "$TEMP_DIR/clawsec-feed.skill" 2>/dev/null; then
# 安全性:检查工件大小(防止 DoS)
ARTIFACT_SIZE=$(stat -c%s "$TEMP_DIR/clawsec-feed.skill" 2>/dev/null || stat -f%z "$TEMP_DIR/clawsec-feed.skill")
MAX_SIZE=$((50 * 1024 * 1024)) # 50MB
if [ "$ARTIFACT_SIZE" -gt "$MAX_SIZE" ]; then
echo "警告:工件过大 ($(( ARTIFACT_SIZE / 1024 / 1024 ))MB),回退到单独文件方式"
else
echo "正在解压工件 ($(( ARTIFACT_SIZE / 1024 ))KB)..."
# 安全性:解压前检查路径遍历
if unzip -l "$TEMP_DIR/clawsec-feed.skill" | grep -qE '\.\./|^/|~/'; then
echo "错误:在工件中检测到路径遍历 - 可能存在安全问题!"
exit 1
fi
# 安全性:检查文件数量(防止 zip 炸弹)
FILE_COUNT=$(unzip -l "$TEMP_DIR/clawsec-feed.skill" | grep -c "^[[:space:]]*[0-9]" || echo 0)
if [ "$FILE_COUNT" -gt 100 ]; then
echo "错误:工件包含文件过多 ($FILE_COUNT) - 可能是 zip 炸弹"
exit 1
fi
# 解压到临时目录
unzip -q "$TEMP_DIR/clawsec-feed.skill" -d "$TEMP_DIR/extracted"
# 验证 skill.json 是否存在
if [ ! -f "$TEMP_DIR/extracted/clawsec-feed/skill.json" ]; then
echo "错误:在工件中未找到 skill.json"
exit 1
fi
# 验证所有解压文件的校验和
echo "正在验证校验和..."
CHECKSUM_FAILED=0
for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do
EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json")
FILE_PATH=$(jq -r --arg f "$file" '.files[$f].path' "$TEMP_DIR/checksums.json")
# 先尝试嵌套路径,然后是扁平文件名
if [ -f "$TEMP_DIR/extracted/clawsec-feed/$FILE_PATH" ]; then
ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawsec-feed/$FILE_PATH" | cut -d' ' -f1)
elif [ -f "$TEMP_DIR/extracted/clawsec-feed/$file" ]; then
ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawsec-feed/$file" | cut -d' ' -f1)
else
echo " ✗ $file (在工件中未找到)"
CHECKSUM_FAILED=1
continue
fi
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo " ✗ $file (校验和不匹配)"
CHECKSUM_FAILED=1
else
echo " ✓ $file"
fi
done
if [ "$CHECKSUM_FAILED" -eq 0 ]; then
# 验证 feed.json 结构(技能特定)
if [ -f "$TEMP_DIR/extracted/clawsec-feed/advisories/feed.json" ]; then
FEED_FILE="$TEMP_DIR/extracted/clawsec-feed/advisories/feed.json"
elif [ -f "$TEMP_DIR/extracted/clawsec-feed/feed.json" ]; then
FEED_FILE="$TEMP_DIR/extracted/clawsec-feed/feed.json"
else
echo "错误:在工件中未找到 feed.json"
exit 1
fi
if ! jq -e '.version and .advisories' "$FEED_FILE" >/dev/null 2>&1; then
echo "错误:feed.json 缺少必需字段 (version, advisories)"
exit 1
fi
# 成功:从工件安装
echo "正在从工件安装..."
mkdir -p "$INSTALL_DIR"
cp -r "$TEMP_DIR/extracted/clawsec-feed"/* "$INSTALL_DIR/"
chmod 600 "$INSTALL_DIR/skill.json"
find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \;
echo "成功:技能已从 .skill 工件安装"
exit 0
else
echo "警告:校验和验证失败,回退到单独文件方式"
fi
fi
fi
# 回退方式:下载单独文件
echo "正在从 checksums.json 清单下载单独文件..."
mkdir -p "$TEMP_DIR/downloads"
DOWNLOAD_FAILED=0
for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do
FILE_URL=$(jq -r --arg f "$file" '.files[$f].url' "$TEMP_DIR/checksums.json")
EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json")
echo "正在下载: $file"
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$FILE_URL" -o "$TEMP_DIR/downloads/$file"; then
echo "错误:无法下载 $file"
DOWNLOAD_FAILED=1
continue
fi
# 立即验证校验和
ACTUAL=$(shasum -a 256 "$TEMP_DIR/downloads/$file" | cut -d' ' -f1)
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo "错误:$file 的校验和不匹配"
DOWNLOAD_FAILED=1
else
echo " ✓ 已验证: $file"
fi
done
if [ "$DOWNLOAD_FAILED" -eq 1 ]; then
echo "错误:单独文件下载失败"
exit 1
fi
# 验证 JSON 文件结构
if ! jq -e '.name and .version' "$TEMP_DIR/downloads/skill.json" >/dev/null 2>&1; then
echo "错误:skill.json 缺少必需字段 (name, version)"
exit 1
fi
if ! jq -e '.version and .advisories' "$TEMP_DIR/downloads/feed.json" >/dev/null 2>&1; then
echo "错误:feed.json 缺少必需字段 (version, advisories)"
exit 1
fi
# 安装文件
echo "正在从单独文件安装..."
mkdir -p "$INSTALL_DIR"
cp "$TEMP_DIR/downloads"/* "$INSTALL_DIR/"
chmod 600 "$INSTALL_DIR/skill.json"
find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \;
echo "成功:技能已从单独文件安装"
将 ClawSec Feed 添加到您的心跳例程:
## ClawSec Feed (每次心跳)
1. 检查安全通告订阅源以获取新的安全警报
2. 与已安装的技能进行交叉引用
3. 如果需要采取行动,则通知用户
告知您的用户:
ClawSec Feed 已成功部署。我现在将:
- 监控社区安全通告订阅源以获取威胁信息
- 提醒您任何影响您环境的安全问题
- 让您了解新出现的攻击模式
订阅社区安全通告订阅源,内容包括:
当发布相关的安全通告时,您的代理将通知您。
# 如果设置了环境变量则使用,否则使用原始 GitHub 订阅源(始终保持最新)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
# 使用错误处理和重试逻辑获取
curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL"
订阅源结构:
{
"version": "1.0",
"updated": "2026-02-02T12:00:00Z",
"advisories": [
{
"id": "GA-2026-001",
"severity": "critical",
"type": "malicious_skill",
"title": "Malicious data exfiltration in skill 'helper-plus'",
"description": "Skill sends user data to external server",
"affected": ["helper-plus@1.0.0", "helper-plus@1.0.1"],
"action": "Remove immediately",
"published": "2026-02-01T10:00:00Z",
"exploitability_score": "critical",
"exploitability_rationale": "Trivially exploitable through normal skill usage; no special conditions required. Active exploitation observed in the wild."
}
]
}
# 如果设置了环境变量则使用,否则使用原始 GitHub 订阅源(始终保持最新)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
TEMP_FEED=$(mktemp)
trap "rm -f '$TEMP_FEED'" EXIT
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then
echo "错误:无法获取安全通告订阅源"
exit 1
fi
# 解析前验证 JSON
if ! jq empty "$TEMP_FEED" 2>/dev/null; then
echo "错误:订阅源中的 JSON 无效"
exit 1
fi
FEED=$(cat "$TEMP_FEED")
# 使用错误处理获取安全通告数量
COUNT=$(echo "$FEED" | jq '.advisories | length')
if [ $? -ne 0 ]; then
echo "错误:无法解析安全通告"
exit 1
fi
echo "安全通告数量: $COUNT"
# 使用 jq 错误处理解析严重安全通告
CRITICAL=$(echo "$FEED" | jq '.advisories[] | select(.severity == "critical")')
if [ $? -ne 0 ]; then
echo "错误:无法筛选严重安全通告"
exit 1
fi
echo "$CRITICAL"
# 使用 UTC 时区以确保日期处理一致
WEEK_AGO=$(TZ=UTC date -v-7d +%Y-%m-%dT00:00:00Z 2>/dev/null || TZ=UTC date -d '7 days ago' +%Y-%m-%dT00:00:00Z)
RECENT=$(echo "$FEED" | jq --arg since "$WEEK_AGO" '.advisories[] | select(.published > $since)')
if [ $? -ne 0 ]; then
echo "错误:无法筛选近期安全通告"
exit 1
fi
echo "$RECENT"
共享的可利用性优先级指导原则维护在:
# 显示特定 CVE 的可利用性详情
CVE_ID="CVE-2026-27488"
echo "$FEED" | jq --arg cve "$CVE_ID" '.advisories[] | select(.id == $cve) | {
id: .id,
severity: .severity,
exploitability_score: .exploitability_score,
exploitability_rationale: .exploitability_rationale,
title: .title
}'
# 按可利用性对安全通告排序(严重 → 高 → 中 → 低)
# 这有助于代理专注于最需要立即采取行动的威胁
echo "$FEED" | jq '[.advisories[] | select(.exploitability_score != null)] |
sort_by(
if .exploitability_score == "critical" then 0
elif .exploitability_score == "high" then 1
elif .exploitability_score == "medium" then 2
elif .exploitability_score == "low" then 3
else 4 end
)'
检查您已安装的技能是否受到安全通告的影响:
# 列出您已安装的技能(根据您的平台调整路径)
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills}"
# 如果设置了环境变量则使用,否则使用原始 GitHub 订阅源(始终保持最新)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
TEMP_FEED=$(mktemp)
trap "rm -f '$TEMP_FEED'" EXIT
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then
echo "错误:无法获取安全通告订阅源"
exit 1
fi
# 验证并解析订阅源
if ! jq empty "$TEMP_FEED" 2>/dev/null; then
echo "错误:订阅源中的 JSON 无效"
exit 1
fi
FEED=$(cat "$TEMP_FEED")
AFFECTED=$(echo "$FEED" | jq -r '.advisories[].affected[]?' 2>/dev/null | sort -u)
if [ $? -ne 0 ]; then
echo "错误:无法从订阅源解析受影响的技能"
exit 1
fi
# 在处理前安全地验证所有已安装的技能
# 这可以防止通过恶意文件名进行 shell 注入
VALIDATED_SKILLS=()
while IFS= read -r -d '' skill_path; do
skill=$(basename "$skill_path")
# 在添加到数组前验证技能名称(防止注入)
if [[ "$skill" =~ ^[a-zA-Z0-9_-]+$ ]]; then
VALIDATED_SKILLS+=("$skill")
else
echo "警告:跳过无效的技能名称: $skill" >&2
fi
done < <(find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
# 针对受影响列表检查每个已验证的技能
# 使用 grep -qF 进行固定字符串匹配(防止正则表达式注入)
for skill in "${VALIDATED_SKILLS[@]}"; do
# 此时,$skill 保证匹配 ^[a-zA-Z0-9_-]+$
if echo "$AFFECTED" | grep -qF "$skill"; then
echo "警告:已安装的技能 '$skill' 存在安全通告!"
# 获取此技能的安全通告详情
echo "$FEED" | jq --arg s "$skill" '.advisories[] | select(.affected[] | contains($s))'
fi
done
如果发现受影响的技能:
| 类型 | 描述 |
|---|---|
malicious_skill | 被识别为故意有害的技能 |
vulnerable_skill | 存在安全漏洞的技能 |
prompt_injection | 已知的提示注入模式 |
attack_pattern | 观察到的攻击技术 |
best_practice | 安全建议 |
| 严重性 | 所需操作 |
|---|---|
critical | 立即通知用户,采取行动 |
high | 尽快通知用户,计划修复 |
medium | 在下一次交互时通知 |
low | 记录以供参考 |
重要提示: 在审查安全通告时,除了严重性之外,始终要按可利用性评分进行优先级排序。可利用性评分表明漏洞在实践中被利用的难易程度,帮助您专注于最需要采取行动的威胁。
| 可利用性 | 含义 | 操作优先级 |
|---|---|---|
high | 可轻易或容易地利用,且有公开工具 | 立即通知 |
medium | 可利用但需要特定条件 | 标准通知 |
low | 难以利用或仅为理论性 | 低优先级通知 |
首先筛选高可利用性:
# 获取高可利用性安全通告
echo "$FEED" | jq '.advisories[] | select(.exploitability_score == "high")'
在通知中包含可利用性:
📡 ClawSec Feed:高可利用性警报
严重 - CVE-2026-27488 (可利用性:高)
→ skill-loader v2.1.0 中可轻易利用的 RCE
→ 公开的漏洞利用代码可用
→ 推荐操作:立即移除或升级到 v2.1.1
按严重性和可利用性进行优先级排序:
当存在多个安全通告时,按以下顺序呈现:
这确保您首先向用户提醒最需要采取行动、立即危险的威胁。
立即通知(严重):
尽快通知(高):
在下一次交互时通知(中):
仅记录(低/信息):
📡 ClawSec Feed:自上次检查后有 2 个新安全通告
严重 - GA-2026-015:恶意提示模式 "ignore-all" (可利用性:高)
→ 检测到提示注入技术。更新您的系统提示防御。
→ 可利用性:使用公开记录的技术可轻易利用。
高 - GA-2026-016:存在漏洞的技能 "data-helper" v1.2.0 (可利用性:中)
→ 您已安装此技能!推荐操作:更新到 v1.2.1 或移除。
→ 可利用性:需要特定配置;不易利用。
订阅源正常 - 已检查安全通告订阅源,无新警报。📡
跟踪上次订阅源检查以识别新的安全通告:
{
"schema_version": "1.0",
"last_feed_check": "2026-02-02T15:00:00Z",
"last_feed_updated": "2026-02-02T12:00:00Z",
"known_advisories": ["GA-2026-001", "GA-2026-002"]
}
保存到:~/.openclaw/clawsec-feed-state.json
STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json"
# 如果状态文件不存在,则创建并设置安全权限
if [ ! -f "$STATE_FILE" ]; then
echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE"
chmod 600 "$STATE_FILE"
fi
# 读取前验证状态文件
if ! jq -e '.schema_version' "$STATE_FILE" >/dev/null 2>&1; then
echo "警告:状态文件损坏或模式无效。正在创建备份并重置。"
cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)"
echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE"
chmod 600 "$STATE_FILE"
fi
# 检查主要版本兼容性
SCHEMA_VER=$(jq -r '.schema_version // "0"' "$STATE_FILE")
if [[ "${SCHEMA_VER%%.*}" != "1" ]]; then
echo "警告:状态文件模式版本 $SCHEMA_VER 可能与此版本不兼容"
fi
# 更新上次检查时间(始终使用 UTC)
TEMP_STATE=$(mktemp)
if jq --arg t "$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)" '.last_feed_check = $t' "$STATE_FILE" > "$TEMP_STATE"; then
mv "$TEMP_STATE" "$STATE_FILE"
chmod 600 "$STATE_FILE"
else
echo "错误:无法更新状态文件"
rm -f "$TEMP_STATE"
fi
重要提示: 为避免对订阅源服务器发出过多请求,请遵循以下指南:
| 检查类型 | 推荐间隔 | 最小间隔 |
|---|---|---|
| 心跳检查 | 每 15-30 分钟 | 5 分钟 |
| 完整订阅源刷新 | 每 1-4 小时 | 30 分钟 |
| 交叉引用扫描 | 每次会话一次 | 5 分钟 |
# 检查自上次检查以来是否已过去足够的时间
STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json"
MIN_INTERVAL_SECONDS=300 # 5 分钟
LAST_CHECK=$(jq -r '.last_feed_check // "1970-01-01T00:00:00Z"' "$STATE_FILE" 2>/dev/null)
LAST_EPOCH=$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST_CHECK" +%s 2>/dev/null || date -d "$LAST_CHECK" +%s 2>/dev/null || echo 0)
NOW_EPOCH=$(TZ=UTC date +%s)
if [ $((NOW_EPOCH - LAST_EPOCH)) -lt $MIN_INTERVAL_SECONDS ]; then
echo "速率限制:上次检查是在不到 5 分钟前。跳过。"
exit 0
fi
| 变量 | 描述 | 默认值 |
|---|---|---|
CLAWSEC_FEED_URL | 自定义安全通告订阅源 URL | 原始 GitHub (main 分支) |
CLAWSEC_INSTALL_DIR | 安装目录 | ~/.openclaw/skills/clawsec-feed |
检查并安装新版本:
# 检查当前安装的版本
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills/clawsec-feed}"
CURRENT_VERSION=$(jq -r '.version' "$INSTALL_DIR/skill.json" 2>/dev/null || echo "unknown")
echo "已安装版本: $CURRENT_VERSION"
# 检查最新可用版本
LATEST_URL="https://api.github.com/repos/prompt-security/ClawSec/releases"
LATEST_VERSION=$(curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$LATEST_URL" 2>/dev/null | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name // empty' | \
sed 's/clawsec-feed-v//')
if [ -z "$LATEST_VERSION" ]; then
echo "警告:无法确定最新版本"
else
echo "最新版本: $LATEST_VERSION"
if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
echo "有可用更新!请使用新版本运行部署步骤。"
else
echo "您正在运行最新版本。"
fi
fi
引导信任问题: 此技能的初始下载无法由技能本身验证。要建立信任:
https://clawsec.prompt.security 下载checksums.json 进行比较:# 下载 SKILL.md 后,验证其完整性
EXPECTED_HASH="<hash-from-checksums.json>"
ACTUAL_HASH=$(shasum -a 256 SKILL.md | cut -d' ' -f1)
if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then
echo "错误:技能文件完整性检查失败!"
echo "此文件可能已被篡改。请勿继续。"
exit 1
fi
注意: 为了最大程度的安全性,请通过单独的受信任渠道验证 checksums.json(例如,直接从 GitHub 发布页面 UI,而不是通过 curl)。
GNU AGPL v3.0 或更高版本 - 详情请参阅仓库。
由 Prompt Security 团队和代理社区使用 📡 构建。
每周安装次数
121
仓库
GitHub 星标数
834
首次出现
2026年2月10日
安全审计
安装于
openclaw114
opencode111
gemini-cli109
cursor108
github-copilot107
codex107
Security advisory feed monitoring for AI agents. Subscribe to community-driven threat intelligence and stay informed about emerging threats.
This feed is automatically updated daily with CVEs related to OpenClaw, clawdbot, and Moltbot from the NIST National Vulnerability Database (NVD).
An open source project byPrompt Security
You can get clawsec-feed in two ways:
If you've installed clawsec-suite, you may already have this!
ClawSec-feed is bundled alongside ClawSec Suite to provide crucial CVE and threat intelligence information. When you install the suite, if you don't already have the feed installed, it will be deployed from the bundled copy.
Advantages:
~/.openclaw/skills/clawsec-feed/Install clawsec-feed independently without the full suite.
When to use standalone:
Advantages:
Continue below for standalone installation instructions.
Installation Steps: Agents should review scripts before execution!
# Get latest clawsec-feed release tag
LATEST_TAG=$(curl -sSL https://api.github.com/repos/prompt-security/ClawSec/releases | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name')
# Download SKILL.md from latest release
SKILL_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG/SKILL.md"
curl -sSL --fail --show-error "$SKILL_URL"
Once you have this skill file, proceed to Deploy ClawSec Feed below.
Installation steps:
mkdir -p ~/.openclaw/skills/clawsec-feed
# Save this SKILL.md as SKILL.md in the directory above
# Get latest release tag with retry logic
LATEST_TAG=$(curl -sSL --retry 3 --retry-delay 1 \
https://api.github.com/repos/prompt-security/ClawSec/releases | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name')
BASE_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG"
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills/clawsec-feed}"
TEMP_DIR=$(mktemp -d)
trap "rm -rf '$TEMP_DIR'" EXIT
# Download checksums.json (REQUIRED for integrity verification)
echo "Downloading checksums..."
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$BASE_URL/checksums.json" -o "$TEMP_DIR/checksums.json"; then
echo "ERROR: Failed to download checksums.json"
exit 1
fi
# Validate checksums.json structure
if ! jq -e '.skill and .version and .files' "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then
echo "ERROR: Invalid checksums.json structure"
exit 1
fi
# PRIMARY: Try .skill artifact
echo "Attempting .skill artifact installation..."
if curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$BASE_URL/clawsec-feed.skill" -o "$TEMP_DIR/clawsec-feed.skill" 2>/dev/null; then
# Security: Check artifact size (prevent DoS)
ARTIFACT_SIZE=$(stat -c%s "$TEMP_DIR/clawsec-feed.skill" 2>/dev/null || stat -f%z "$TEMP_DIR/clawsec-feed.skill")
MAX_SIZE=$((50 * 1024 * 1024)) # 50MB
if [ "$ARTIFACT_SIZE" -gt "$MAX_SIZE" ]; then
echo "WARNING: Artifact too large ($(( ARTIFACT_SIZE / 1024 / 1024 ))MB), falling back to individual files"
else
echo "Extracting artifact ($(( ARTIFACT_SIZE / 1024 ))KB)..."
# Security: Check for path traversal before extraction
if unzip -l "$TEMP_DIR/clawsec-feed.skill" | grep -qE '\.\./|^/|~/'; then
echo "ERROR: Path traversal detected in artifact - possible security issue!"
exit 1
fi
# Security: Check file count (prevent zip bomb)
FILE_COUNT=$(unzip -l "$TEMP_DIR/clawsec-feed.skill" | grep -c "^[[:space:]]*[0-9]" || echo 0)
if [ "$FILE_COUNT" -gt 100 ]; then
echo "ERROR: Artifact contains too many files ($FILE_COUNT) - possible zip bomb"
exit 1
fi
# Extract to temp directory
unzip -q "$TEMP_DIR/clawsec-feed.skill" -d "$TEMP_DIR/extracted"
# Verify skill.json exists
if [ ! -f "$TEMP_DIR/extracted/clawsec-feed/skill.json" ]; then
echo "ERROR: skill.json not found in artifact"
exit 1
fi
# Verify checksums for all extracted files
echo "Verifying checksums..."
CHECKSUM_FAILED=0
for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do
EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json")
FILE_PATH=$(jq -r --arg f "$file" '.files[$f].path' "$TEMP_DIR/checksums.json")
# Try nested path first, then flat filename
if [ -f "$TEMP_DIR/extracted/clawsec-feed/$FILE_PATH" ]; then
ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawsec-feed/$FILE_PATH" | cut -d' ' -f1)
elif [ -f "$TEMP_DIR/extracted/clawsec-feed/$file" ]; then
ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawsec-feed/$file" | cut -d' ' -f1)
else
echo " ✗ $file (not found in artifact)"
CHECKSUM_FAILED=1
continue
fi
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo " ✗ $file (checksum mismatch)"
CHECKSUM_FAILED=1
else
echo " ✓ $file"
fi
done
if [ "$CHECKSUM_FAILED" -eq 0 ]; then
# Validate feed.json structure (skill-specific)
if [ -f "$TEMP_DIR/extracted/clawsec-feed/advisories/feed.json" ]; then
FEED_FILE="$TEMP_DIR/extracted/clawsec-feed/advisories/feed.json"
elif [ -f "$TEMP_DIR/extracted/clawsec-feed/feed.json" ]; then
FEED_FILE="$TEMP_DIR/extracted/clawsec-feed/feed.json"
else
echo "ERROR: feed.json not found in artifact"
exit 1
fi
if ! jq -e '.version and .advisories' "$FEED_FILE" >/dev/null 2>&1; then
echo "ERROR: feed.json missing required fields (version, advisories)"
exit 1
fi
# SUCCESS: Install from artifact
echo "Installing from artifact..."
mkdir -p "$INSTALL_DIR"
cp -r "$TEMP_DIR/extracted/clawsec-feed"/* "$INSTALL_DIR/"
chmod 600 "$INSTALL_DIR/skill.json"
find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \;
echo "SUCCESS: Skill installed from .skill artifact"
exit 0
else
echo "WARNING: Checksum verification failed, falling back to individual files"
fi
fi
fi
# FALLBACK: Download individual files
echo "Downloading individual files from checksums.json manifest..."
mkdir -p "$TEMP_DIR/downloads"
DOWNLOAD_FAILED=0
for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do
FILE_URL=$(jq -r --arg f "$file" '.files[$f].url' "$TEMP_DIR/checksums.json")
EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json")
echo "Downloading: $file"
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \
"$FILE_URL" -o "$TEMP_DIR/downloads/$file"; then
echo "ERROR: Failed to download $file"
DOWNLOAD_FAILED=1
continue
fi
# Verify checksum immediately
ACTUAL=$(shasum -a 256 "$TEMP_DIR/downloads/$file" | cut -d' ' -f1)
if [ "$EXPECTED" != "$ACTUAL" ]; then
echo "ERROR: Checksum mismatch for $file"
DOWNLOAD_FAILED=1
else
echo " ✓ Verified: $file"
fi
done
if [ "$DOWNLOAD_FAILED" -eq 1 ]; then
echo "ERROR: Individual file download failed"
exit 1
fi
# Validate JSON files structure
if ! jq -e '.name and .version' "$TEMP_DIR/downloads/skill.json" >/dev/null 2>&1; then
echo "ERROR: skill.json missing required fields (name, version)"
exit 1
fi
if ! jq -e '.version and .advisories' "$TEMP_DIR/downloads/feed.json" >/dev/null 2>&1; then
echo "ERROR: feed.json missing required fields (version, advisories)"
exit 1
fi
# Install files
echo "Installing from individual files..."
mkdir -p "$INSTALL_DIR"
cp "$TEMP_DIR/downloads"/* "$INSTALL_DIR/"
chmod 600 "$INSTALL_DIR/skill.json"
find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \;
echo "SUCCESS: Skill installed from individual files"
Add ClawSec Feed to your heartbeat routine:
## ClawSec Feed (every heartbeat)
1. Check advisory feed for new security alerts
2. Cross-reference with installed skills
3. Notify user if action is required
Tell your user:
ClawSec Feed deployed successfully. I will now:
- Monitor the community advisory feed for threats
- Alert you to any security issues affecting your environment
- Keep you informed of emerging attack patterns
Subscribes to the community advisory feed for:
When a relevant advisory is published, your agent will notify you.
# Use environment variable if set, otherwise use raw GitHub feed (always up-to-date)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
# Fetch with error handling and retry logic
curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL"
Feed structure:
{
"version": "1.0",
"updated": "2026-02-02T12:00:00Z",
"advisories": [
{
"id": "GA-2026-001",
"severity": "critical",
"type": "malicious_skill",
"title": "Malicious data exfiltration in skill 'helper-plus'",
"description": "Skill sends user data to external server",
"affected": ["helper-plus@1.0.0", "helper-plus@1.0.1"],
"action": "Remove immediately",
"published": "2026-02-01T10:00:00Z",
"exploitability_score": "critical",
"exploitability_rationale": "Trivially exploitable through normal skill usage; no special conditions required. Active exploitation observed in the wild."
}
]
}
# Use environment variable if set, otherwise use raw GitHub feed (always up-to-date)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
TEMP_FEED=$(mktemp)
trap "rm -f '$TEMP_FEED'" EXIT
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then
echo "Error: Failed to fetch advisory feed"
exit 1
fi
# Validate JSON before parsing
if ! jq empty "$TEMP_FEED" 2>/dev/null; then
echo "Error: Invalid JSON in feed"
exit 1
fi
FEED=$(cat "$TEMP_FEED")
# Get advisory count with error handling
COUNT=$(echo "$FEED" | jq '.advisories | length')
if [ $? -ne 0 ]; then
echo "Error: Failed to parse advisories"
exit 1
fi
echo "Advisory count: $COUNT"
# Parse critical advisories with jq error handling
CRITICAL=$(echo "$FEED" | jq '.advisories[] | select(.severity == "critical")')
if [ $? -ne 0 ]; then
echo "Error: Failed to filter critical advisories"
exit 1
fi
echo "$CRITICAL"
# Use UTC timezone for consistent date handling
WEEK_AGO=$(TZ=UTC date -v-7d +%Y-%m-%dT00:00:00Z 2>/dev/null || TZ=UTC date -d '7 days ago' +%Y-%m-%dT00:00:00Z)
RECENT=$(echo "$FEED" | jq --arg since "$WEEK_AGO" '.advisories[] | select(.published > $since)')
if [ $? -ne 0 ]; then
echo "Error: Failed to filter recent advisories"
exit 1
fi
echo "$RECENT"
Shared exploitability prioritization guidance is maintained in:
wiki/exploitability-scoring.mdskills/clawsec-suite/SKILL.md ("Quick feed check")# Show exploitability details for a specific CVE
CVE_ID="CVE-2026-27488"
echo "$FEED" | jq --arg cve "$CVE_ID" '.advisories[] | select(.id == $cve) | {
id: .id,
severity: .severity,
exploitability_score: .exploitability_score,
exploitability_rationale: .exploitability_rationale,
title: .title
}'
# Sort advisories by exploitability (critical → high → medium → low)
# This helps agents focus on the most immediately actionable threats
echo "$FEED" | jq '[.advisories[] | select(.exploitability_score != null)] |
sort_by(
if .exploitability_score == "critical" then 0
elif .exploitability_score == "high" then 1
elif .exploitability_score == "medium" then 2
elif .exploitability_score == "low" then 3
else 4 end
)'
Check if any of your installed skills are affected by advisories:
# List your installed skills (adjust path for your platform)
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills}"
# Use environment variable if set, otherwise use raw GitHub feed (always up-to-date)
DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json"
FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}"
TEMP_FEED=$(mktemp)
trap "rm -f '$TEMP_FEED'" EXIT
if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then
echo "Error: Failed to fetch advisory feed"
exit 1
fi
# Validate and parse feed
if ! jq empty "$TEMP_FEED" 2>/dev/null; then
echo "Error: Invalid JSON in feed"
exit 1
fi
FEED=$(cat "$TEMP_FEED")
AFFECTED=$(echo "$FEED" | jq -r '.advisories[].affected[]?' 2>/dev/null | sort -u)
if [ $? -ne 0 ]; then
echo "Error: Failed to parse affected skills from feed"
exit 1
fi
# Safely validate all installed skills before processing
# This prevents shell injection via malicious filenames
VALIDATED_SKILLS=()
while IFS= read -r -d '' skill_path; do
skill=$(basename "$skill_path")
# Validate skill name BEFORE adding to array (prevents injection)
if [[ "$skill" =~ ^[a-zA-Z0-9_-]+$ ]]; then
VALIDATED_SKILLS+=("$skill")
else
echo "Warning: Skipping invalid skill name: $skill" >&2
fi
done < <(find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null)
# Check each validated skill against affected list
# Use grep -qF for fixed string matching (prevents regex injection)
for skill in "${VALIDATED_SKILLS[@]}"; do
# At this point, $skill is guaranteed to match ^[a-zA-Z0-9_-]+$
if echo "$AFFECTED" | grep -qF "$skill"; then
echo "WARNING: Installed skill '$skill' has a security advisory!"
# Get advisory details for this skill
echo "$FEED" | jq --arg s "$skill" '.advisories[] | select(.affected[] | contains($s))'
fi
done
If you find affected skills:
| Type | Description |
|---|---|
malicious_skill | Skill identified as intentionally harmful |
vulnerable_skill | Skill with security vulnerabilities |
prompt_injection | Known prompt injection pattern |
attack_pattern | Observed attack technique |
best_practice | Security recommendation |
| Severity | Action Required |
|---|---|
critical | Notify user immediately, take action |
high | Notify user soon, plan remediation |
medium | Notify at next interaction |
low | Log for reference |
IMPORTANT: When reviewing advisories, always prioritize by exploitability score in addition to severity. The exploitability score indicates how easily a vulnerability can be exploited in practice, helping you focus on the most actionable threats.
| Exploitability | Meaning | Action Priority |
|---|---|---|
high | Trivially or easily exploitable with public tooling | Immediate notification |
medium | Exploitable but requires specific conditions | Standard notification |
low | Difficult to exploit or theoretical | Low priority notification |
Filter for high-exploitability first:
# Get high exploitability advisories
echo "$FEED" | jq '.advisories[] | select(.exploitability_score == "high")'
Include exploitability in notifications:
📡 ClawSec Feed: High-exploitability alert
CRITICAL - CVE-2026-27488 (Exploitability: HIGH)
→ Trivially exploitable RCE in skill-loader v2.1.0
→ Public exploit code available
→ Recommended action: Immediate removal or upgrade to v2.1.1
Prioritize by both severity AND exploitability:
When multiple advisories exist, present them in this order:
This ensures you alert users to the most actionable, immediately dangerous threats first.
Notify Immediately (Critical):
Notify Soon (High):
Notify at Next Interaction (Medium):
Log Only (Low/Info):
📡 ClawSec Feed: 2 new advisories since last check
CRITICAL - GA-2026-015: Malicious prompt pattern "ignore-all" (Exploitability: HIGH)
→ Detected prompt injection technique. Update your system prompt defenses.
→ Exploitability: Easily exploitable with publicly documented techniques.
HIGH - GA-2026-016: Vulnerable skill "data-helper" v1.2.0 (Exploitability: MEDIUM)
→ You have this installed! Recommended action: Update to v1.2.1 or remove.
→ Exploitability: Requires specific configuration; not trivially exploitable.
FEED_OK - Advisory feed checked, no new alerts. 📡
Track the last feed check to identify new advisories:
{
"schema_version": "1.0",
"last_feed_check": "2026-02-02T15:00:00Z",
"last_feed_updated": "2026-02-02T12:00:00Z",
"known_advisories": ["GA-2026-001", "GA-2026-002"]
}
Save to: ~/.openclaw/clawsec-feed-state.json
STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json"
# Create state file with secure permissions if it doesn't exist
if [ ! -f "$STATE_FILE" ]; then
echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE"
chmod 600 "$STATE_FILE"
fi
# Validate state file before reading
if ! jq -e '.schema_version' "$STATE_FILE" >/dev/null 2>&1; then
echo "Warning: State file corrupted or invalid schema. Creating backup and resetting."
cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)"
echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE"
chmod 600 "$STATE_FILE"
fi
# Check for major version compatibility
SCHEMA_VER=$(jq -r '.schema_version // "0"' "$STATE_FILE")
if [[ "${SCHEMA_VER%%.*}" != "1" ]]; then
echo "Warning: State file schema version $SCHEMA_VER may not be compatible with this version"
fi
# Update last check time (always use UTC)
TEMP_STATE=$(mktemp)
if jq --arg t "$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)" '.last_feed_check = $t' "$STATE_FILE" > "$TEMP_STATE"; then
mv "$TEMP_STATE" "$STATE_FILE"
chmod 600 "$STATE_FILE"
else
echo "Error: Failed to update state file"
rm -f "$TEMP_STATE"
fi
Important: To avoid excessive requests to the feed server, follow these guidelines:
| Check Type | Recommended Interval | Minimum Interval |
|---|---|---|
| Heartbeat check | Every 15-30 minutes | 5 minutes |
| Full feed refresh | Every 1-4 hours | 30 minutes |
| Cross-reference scan | Once per session | 5 minutes |
# Check if enough time has passed since last check
STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json"
MIN_INTERVAL_SECONDS=300 # 5 minutes
LAST_CHECK=$(jq -r '.last_feed_check // "1970-01-01T00:00:00Z"' "$STATE_FILE" 2>/dev/null)
LAST_EPOCH=$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST_CHECK" +%s 2>/dev/null || date -d "$LAST_CHECK" +%s 2>/dev/null || echo 0)
NOW_EPOCH=$(TZ=UTC date +%s)
if [ $((NOW_EPOCH - LAST_EPOCH)) -lt $MIN_INTERVAL_SECONDS ]; then
echo "Rate limit: Last check was less than 5 minutes ago. Skipping."
exit 0
fi
| Variable | Description | Default |
|---|---|---|
CLAWSEC_FEED_URL | Custom advisory feed URL | Raw GitHub (main branch) |
CLAWSEC_INSTALL_DIR | Installation directory | ~/.openclaw/skills/clawsec-feed |
Check for and install newer versions:
# Check current installed version
INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills/clawsec-feed}"
CURRENT_VERSION=$(jq -r '.version' "$INSTALL_DIR/skill.json" 2>/dev/null || echo "unknown")
echo "Installed version: $CURRENT_VERSION"
# Check latest available version
LATEST_URL="https://api.github.com/repos/prompt-security/ClawSec/releases"
LATEST_VERSION=$(curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$LATEST_URL" 2>/dev/null | \
jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name // empty' | \
sed 's/clawsec-feed-v//')
if [ -z "$LATEST_VERSION" ]; then
echo "Warning: Could not determine latest version"
else
echo "Latest version: $LATEST_VERSION"
if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then
echo "Update available! Run the deployment steps with the new version."
else
echo "You are running the latest version."
fi
fi
Bootstrap Trust Problem: The initial download of this skill cannot be verified by the skill itself. To establish trust:
https://clawsec.prompt.securitychecksums.json:# After downloading SKILL.md, verify its integrity
EXPECTED_HASH="<hash-from-checksums.json>"
ACTUAL_HASH=$(shasum -a 256 SKILL.md | cut -d' ' -f1)
if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then
echo "ERROR: Skill file integrity check failed!"
echo "This file may have been tampered with. Do not proceed."
exit 1
fi
Note: For maximum security, verify checksums.json via a separate trusted channel (e.g., direct from GitHub release page UI, not via curl).
GNU AGPL v3.0 or later - See repository for details.
Built with 📡 by the Prompt Security team and the agent community.
Weekly Installs
121
Repository
GitHub Stars
834
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
openclaw114
opencode111
gemini-cli109
cursor108
github-copilot107
codex107
GitHub Actions 官方文档查询助手 - 精准解答 CI/CD 工作流问题
43,400 周安装