Skill Trust Decision

forest-carbon-estimate

技能功能合法(森林碳储量估算),但存在硬编码密码违反最佳实践、凭证系统理论上面可被滥用于外传但实际未被调用、文档声称纯本地处理但代码有网络依赖等问题,均属轻微瑕疵,不影响整体安全。

Install decision first Source: ClawHub Scanned: Jul 27, 2026
Files 20
Artifacts 15
Violations 2
Findings 5

Why this conclusion was reached

1/4 dimensions flagged
Block
Declared vs actual capability

2 undeclared or violating capabilities were inferred.

Review
Hidden execution and egress

15 lower-risk artifacts were extracted and still need context.

Pass
Attack chain and severe findings

There is no explicit malicious chain in the report.

Pass
Dependencies and supply chain hygiene

Dependencies are present but no obvious high-risk issue stands out.

What drove the risk score up

源代码中硬编码 NASA Earthdata 默认密码 +15

_geoskill_core/credentials.py:_DEFAULTS 字典包含明文用户名 'ruiduobao' 和密码 'Ruiduobao123',违反源码安全最佳实践

凭证系统设计可被滥用(影子功能) +5

credentials.py 提供了完整的凭证解析链(env→secrets.json→.netrc→默认值),理论上可被恶意修改调用 get_openai_key() 等函数外传凭证,但当前 skill 代码未调用任何凭证获取函数

SKILL.md 声明与实际行为轻微不符 +5

Privacy Disclosure 声称'无数据发送到任何服务器',但代码依赖 Open-Meteo 和 Nominatim 在线 geocoding(aoi.py);_resolve_place 依赖不存在的外部 _shared/place_resolver.py

Most important evidence

Low Supply Chain

硬编码明文默认密码

_geoskill_core/credentials.py 第 68-70 行定义了 _DEFAULTS 字典,包含明文 NASA Earthdata 用户名 'ruiduobao' 和密码 'Ruiduobao123'。虽然设计文档声称'这些值通过 helper 间接使用,不应出现在 skill 源码/日志/文档/报告里',但它们仍然是可读的 Python 模块级常量,且该模块已被 vendoring 到当前 skill。若此文件被意外 import 且环境变量均未设置,会 fallback 到这些硬编码值(仅被 _resolve() 使用,当前 skill 未调用)。

_geoskill_core/credentials.py:68
将默认密码改为空字符串或占位符,强制用户通过环境变量或 secrets.json 提供真实凭证
Info Doc Mismatch

Privacy Disclosure 声明与实际网络行为轻微不符

SKILL.md 第 10-11 行声明'This tool processes data locally. No data is sent to any server.'。但 scripts/forest-carbon-estimate.py 的 _resolve_place() 和 from-canopy-height 命令会通过 _geoskill_core/aoi.py 发起对 https://geocoding-api.open-meteo.com 和 https://nominatim.openstreetmap.org 的 HTTP 请求,用于地名解析。这是实现合理功能所必需的,但未在文档中声明。

SKILL.md:10
在 SKILL.md 的 Privacy Disclosure 或 Troubleshooting 节明确列出所需网络端点(Open-Meteo geocoding API、Nominatim)
Info Doc Mismatch

_resolve_place 依赖不存在的外部模块

scripts/forest-carbon-estimate.py 的 _resolve_place() 函数(行 27-43)尝试从 '../_shared/place_resolver.py' 或 './_shared/place_resolver.py' 加载 place_resolver 模块。该路径不存在于当前 skill,调用会抛出 ValueError。这是未 vendoring 的外部依赖,SKILL.md 也未提及此功能的前置条件。

scripts/forest-carbon-estimate.py:27
正式将 place_resolver.py vendoring 到 _geoskill_core,或在 SKILL.md 中声明此为 Phase 0 DISABLED 功能
Info RCE

cmd_from_canopy_height 的 importlib 代码块永不可达

scripts/forest-carbon-estimate.py 的 cmd_from_canopy_height 函数在 'return 0' 之后(行 ~350+)有一段通过 importlib.util.spec_from_file_location 加载外部 from_stac.py 的代码块。由于前面的 'return 0' 语句在所有正常执行路径上都会退出函数,这段代码在任何条件下都不会执行,构成死代码。

scripts/forest-carbon-estimate.py:340
删除死代码或重构为有效逻辑
Info Sensitive Access

credentials.py 支持读取 ~/.netrc 和 ~/.geoskill/secrets.json

_geoskill_core/credentials.py 的 _read_netrc() 和 load_user_secrets() 函数会读取用户 home 目录下的 .netrc 和 ~/.geoskill/secrets.json 文件。虽然这是合法的凭证管理模式,但 SKILL.md 未声明此能力,且当前 skill 代码本身并未调用这些凭证获取函数——它们只是被 vendoring 进来而未被使用。

_geoskill_core/credentials.py:106
如果当前 skill 不需要这些凭证功能,不必将整个 credentials.py 模块 vendoring 进来

Declared capability vs actual capability

Filesystem Pass
Declared READ
→
Inferred WRITE
scripts/forest-carbon-estimate.py:process_raster 读写 GeoTIFF;write_raster 写输出文件,声明中'本地处理'与之一致
Network Block
Declared NONE
→
Inferred READ
_geoskill_core/aoi.py:_open_meteo_search/_nominatim_search 发起 HTTP 请求到外部 API,但 SKILL.md 未声明
Environment Block
Declared NONE
→
Inferred READ
_geoskill_core/credentials.py:_resolve() 通过 os.environ.get 读取环境变量,但 SKILL.md 和主脚本均未声明
Shell Pass
Declared NONE
→
Inferred NONE
未发现 subprocess / shell=True / os.system 等 shell 执行调用

Suspicious artifacts and egress

Medium External URL
https://www.globalforestwatch.org/

README.md:183

Medium External URL
https://gedi.umd.edu/

README.md:184

Medium External URL
https://www.ipcc-nggip.iges.or.jp/public/2006gl/

README.md:203

Medium External URL
https://www.ipcc-nggip.iges.or.jp/public/2019rf/

README.md:210

Medium External URL
https://clawhub.ai

_geoskill_core/aoi.py:99

Medium External URL
https://geocoding-api.open-meteo.com/v1/search

_geoskill_core/aoi.py:234

Medium External URL
https://nominatim.openstreetmap.org/search

_geoskill_core/aoi.py:272

Medium External URL
https://urs.earthdata.nasa.gov/users/new/

_geoskill_core/credentials.py:302

Medium External URL
https://urs.earthdata.nasa.gov/profile

_geoskill_core/credentials.py:306

Medium External URL
https://firms.modaps.eosdis.nasa.gov/api/map_key/

_geoskill_core/credentials.py:308

Medium External URL
http://data.cma.cn/

_geoskill_core/credentials.py:310

Medium External URL
https://eogdata.mines.edu/register/

_geoskill_core/credentials.py:314

Dependencies and supply chain

PackageVersionSourceKnown vulnNotes
numpy >=1.21.0 pip No 无上限锁定
rasterio >=1.3.0 pip No 无上限锁定

File composition

20 files · 4378 lines
Python 11 files · 3395 linesMarkdown 5 files · 945 linesOther 1 files · 21 linesText 2 files · 14 linesYAML 1 files · 3 lines
Files of concern · 5
_geoskill_core/credentials.py Python · 317 lines
硬编码明文默认密码 · credentials.py 支持读取 ~/.netrc 和 ~/.geoskill/secrets.json · https://urs.earthdata.nasa.gov/users/new/ · https://urs.earthdata.nasa.gov/profile · https://firms.modaps.eosdis.nasa.gov/api/map_key/ · http://data.cma.cn/ · https://eogdata.mines.edu/register/
scripts/forest-carbon-estimate.py Python · 1035 lines
_resolve_place 依赖不存在的外部模块 · cmd_from_canopy_height 的 importlib 代码块永不可达 · https://planetarycomputer.microsoft.com/stac
_geoskill_core/aoi.py Python · 507 lines
https://clawhub.ai · https://geocoding-api.open-meteo.com/v1/search · https://nominatim.openstreetmap.org/search
README.md Markdown · 343 lines
https://www.globalforestwatch.org/ · https://gedi.umd.edu/ · https://www.ipcc-nggip.iges.or.jp/public/2006gl/ · https://www.ipcc-nggip.iges.or.jp/public/2019rf/
SKILL.md Markdown · 343 lines
Privacy Disclosure 声明与实际网络行为轻微不符
Other files · sensors.py · test_forest-carbon-estimate.py · manifest.py · safe_download.py · checks.py · details.md +1

Security positives

无恶意行为:无 base64 解码、eval()、subprocess / shell 执行、反向 shell 或 C2 通信
无凭证外传:虽然 credentials.py 提供了凭证获取接口,但当前 skill 代码中没有任何调用点主动外传凭证
依赖已版本锁定:requirements.txt 明确指定 numpy>=1.21.0, rasterio>=1.3.0
网络请求仅限合法公共服务:Open-Meteo geocoding API 和 Nominatim,无裸 IP 请求
文件写入限于输出目录:GeoTIFF/CSV 输出由用户指定路径,无遍历敏感路径行为
代码结构清晰:_geoskill_core 各模块职责明确(aoi/safe_download/manifest/errors/credentials)