|
|
|
|
@@ -0,0 +1,84 @@
|
|
|
|
|
# Security Findings Re-Triage (2026-03-29)
|
|
|
|
|
|
|
|
|
|
This document is the current-head refresh of the historical
|
|
|
|
|
[`security-findings-triage-2026-03-15.md`](security-findings-triage-2026-03-15.md)
|
|
|
|
|
baseline.
|
|
|
|
|
|
|
|
|
|
- Baseline snapshot: `origin/main@226f10c2a62fc182b4e93458bddea2e60f9b0cb9`
|
|
|
|
|
- Current verification target: `main@d63d99381b8f613f99c8cb7b758e7879b401f8a0`
|
|
|
|
|
- The 2026-03-15 markdown file and CSV remain useful as historical input, not
|
|
|
|
|
as the current source of truth.
|
|
|
|
|
- Status meanings are unchanged:
|
|
|
|
|
`still present and exploitable`, `still present but low practical risk`,
|
|
|
|
|
`obsolete/not reproducible on current HEAD`, `duplicate of another finding`.
|
|
|
|
|
|
|
|
|
|
## Summary On Current HEAD
|
|
|
|
|
|
|
|
|
|
- still present and exploitable: 0
|
|
|
|
|
- still present but low practical risk: 0
|
|
|
|
|
- obsolete/not reproducible on current HEAD: 26
|
|
|
|
|
- duplicate of another finding: 7
|
|
|
|
|
|
|
|
|
|
## High-Level Outcome
|
|
|
|
|
|
|
|
|
|
The 2026-03-15 finding set no longer contains a currently reproduced open
|
|
|
|
|
security issue on `main`.
|
|
|
|
|
|
|
|
|
|
The biggest shifts since the original baseline are:
|
|
|
|
|
|
|
|
|
|
- filesystem/symlink hardening in `setup_web.js`, `install.js`,
|
|
|
|
|
`sync_microsoft_skills.py`, `generate_index.py`, `fix_skills_metadata.py`,
|
|
|
|
|
and `skill-utils.js`
|
|
|
|
|
- removal of shared frontend writes for skill saves/stars
|
|
|
|
|
- parser hardening for non-mapping YAML frontmatter
|
|
|
|
|
- secure extraction in the Office unpack helpers
|
|
|
|
|
- migration of predictable `/tmp` state files into user-owned state
|
|
|
|
|
directories
|
|
|
|
|
- documentation hardening for risky command guidance
|
|
|
|
|
|
|
|
|
|
## Detailed Findings
|
|
|
|
|
|
|
|
|
|
| # | Current Status | Current HEAD Rationale | Evidence |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| 1 | obsolete/not reproducible on current HEAD | `sync_microsoft_skills.py` now sanitizes flat names and constrains delete/copy targets to safe in-repo paths. | `tools/scripts/sync_microsoft_skills.py`, `tools/scripts/tests/test_sync_microsoft_skills_security.py` |
|
|
|
|
|
| 2 | obsolete/not reproducible on current HEAD | `SkillDetail.tsx` still renders markdown without `rehype-raw`; the reported stored-XSS path does not reproduce. | `apps/web-app/src/pages/SkillDetail.tsx` |
|
|
|
|
|
| 3 | obsolete/not reproducible on current HEAD | `setup_web.js` now uses `lstatSync` plus `resolveSafeRealPath()` and skips out-of-root symlinks instead of dereferencing them into public assets. | `tools/scripts/setup_web.js`, `tools/scripts/tests/copy_security.test.js` |
|
|
|
|
|
| 4 | obsolete/not reproducible on current HEAD | The Apify skill no longer recommends pipe-to-shell installs or token-on-command-line login; the risky documentation pattern was removed. | `skills/apify-actorization/SKILL.md` |
|
|
|
|
|
| 5 | duplicate of another finding | Still the same root cause/fix area as finding `3`. | `tools/scripts/setup_web.js` |
|
|
|
|
|
| 6 | duplicate of another finding | Still the same root cause/fix area as finding `3`. | `tools/scripts/setup_web.js` |
|
|
|
|
|
| 7 | obsolete/not reproducible on current HEAD | Microsoft sync now rejects unsafe symlink targets and only accepts safe regular files that stay within the cloned source root. | `tools/scripts/sync_microsoft_skills.py`, `tools/scripts/tests/test_sync_microsoft_skills_security.py` |
|
|
|
|
|
| 8 | duplicate of another finding | Still the same root cause/fix area as finding `7`. | `tools/scripts/sync_microsoft_skills.py` |
|
|
|
|
|
| 9 | obsolete/not reproducible on current HEAD | The tracked `__pycache__` artifacts are absent on current `main`, and repo hygiene tests explicitly fail if they reappear. | `tools/scripts/tests/repo_hygiene_security.test.js` |
|
|
|
|
|
| 10 | obsolete/not reproducible on current HEAD | `generate_index.py` now ignores symlinked `SKILL.md` files instead of reading them during index generation. | `tools/scripts/generate_index.py`, `tools/scripts/tests/test_frontmatter_parsing_security.py` |
|
|
|
|
|
| 11 | obsolete/not reproducible on current HEAD | The Jetski loader rejects symlinked skill directories/files and refuses any resolved `SKILL.md` outside the configured skills root. | `docs/integrations/jetski-gemini-loader/loader.mjs`, `tools/scripts/tests/jetski_gemini_loader.test.cjs` |
|
|
|
|
|
| 12 | obsolete/not reproducible on current HEAD | TLS verification is enabled by default again; insecure behavior now requires an explicit opt-out environment flag. | `skills/junta-leiloeiros/scripts/scraper/base_scraper.py`, `skills/junta-leiloeiros/scripts/web_scraper_fallback.py` |
|
|
|
|
|
| 13 | obsolete/not reproducible on current HEAD | The old bundle-category omission path still does not drive shipped bundle output; current bundles come from `build-catalog.js`. | `tools/scripts/build-catalog.js`, `data/bundles.json` |
|
|
|
|
|
| 14 | obsolete/not reproducible on current HEAD | The malformed `--- Unknown` frontmatter regression is no longer present in `alpha-vantage`. | `skills/alpha-vantage/SKILL.md`, `tools/scripts/tests/repo_hygiene_security.test.js` |
|
|
|
|
|
| 15 | obsolete/not reproducible on current HEAD | `ws_listener.py` now defaults to a user-owned state directory and uses secure file creation instead of predictable shared `/tmp` output files. | `skills/videodb/scripts/ws_listener.py`, `tools/scripts/tests/local_temp_safety.test.js` |
|
|
|
|
|
| 16 | obsolete/not reproducible on current HEAD | `refresh-skills-plugin.js` now resolves real paths under the skills root before serving `/skills/*`; the public Pages app also no longer exposes the maintainer sync surface. | `apps/web-app/refresh-skills-plugin.js`, `README.md`, `apps/web-app/README.md` |
|
|
|
|
|
| 17 | duplicate of another finding | Still the same root cause/fix area as finding `16`. | `apps/web-app/refresh-skills-plugin.js` |
|
|
|
|
|
| 18 | obsolete/not reproducible on current HEAD | `validate_skills.py` now rejects non-mapping YAML frontmatter cleanly instead of crashing downstream validation. | `tools/scripts/validate_skills.py`, `tools/scripts/tests/test_frontmatter_parsing_security.py` |
|
|
|
|
|
| 19 | obsolete/not reproducible on current HEAD | `useSkillStars` now stores saves locally in the browser and no longer performs shared frontend writes through the public Supabase client. | `apps/web-app/src/hooks/useSkillStars.ts`, `apps/web-app/src/lib/supabase.ts` |
|
|
|
|
|
| 20 | obsolete/not reproducible on current HEAD | `fix_skills_metadata.py` now skips symlinked `SKILL.md` files and non-mapping frontmatter instead of rewriting arbitrary targets. | `tools/scripts/fix_skills_metadata.py` |
|
|
|
|
|
| 21 | obsolete/not reproducible on current HEAD | `install.js` now uses `lstatSync` plus `resolveSafeRealPath()` and skips symlinks that resolve outside the cloned repo root. | `tools/bin/install.js`, `tools/scripts/tests/copy_security.test.js` |
|
|
|
|
|
| 22 | duplicate of another finding | Still the same root cause/fix area as finding `21`. | `tools/bin/install.js` |
|
|
|
|
|
| 23 | duplicate of another finding | Still the same root cause/fix area as finding `1`. | `tools/scripts/sync_microsoft_skills.py` |
|
|
|
|
|
| 24 | obsolete/not reproducible on current HEAD | The audio transcription example now uses a quoted heredoc and passes values via environment variables instead of interpolating them into Python source. | `skills/audio-transcriber/examples/basic-transcription.sh` |
|
|
|
|
|
| 25 | obsolete/not reproducible on current HEAD | The claimed recursive symlink traversal in catalog discovery still does not reproduce on current code paths. | `tools/lib/skill-utils.js`, `tools/scripts/build-catalog.js` |
|
|
|
|
|
| 26 | obsolete/not reproducible on current HEAD | Root `skills_index.json` remains the canonical generated index, so the reported release-script path mismatch does not reproduce as a defect. | `tools/scripts/generate_index.py`, `tools/scripts/update_readme.py`, `tools/scripts/release_workflow.js` |
|
|
|
|
|
| 27 | obsolete/not reproducible on current HEAD | `skill-utils.js` now relies on `lstatSync`-based safe directory/file discovery, so normalization does not treat symlinked skill folders as writable local skills. | `tools/lib/skill-utils.js`, `tools/scripts/normalize-frontmatter.js` |
|
|
|
|
|
| 28 | obsolete/not reproducible on current HEAD | The `last30days` skill still passes `"$ARGUMENTS"` as a quoted value into a temp file, so the reported direct shell-injection sink does not reproduce from current text. | `skills/last30days/SKILL.md` |
|
|
|
|
|
| 29 | duplicate of another finding | Still the same root cause/fix area as finding `18`. | `tools/scripts/generate_index.py`, `tools/scripts/validate_skills.py` |
|
|
|
|
|
| 30 | obsolete/not reproducible on current HEAD | The strategic compact hook now stores state under `XDG_STATE_HOME` instead of predictable shared `/tmp` paths. | `skills/cc-skill-strategic-compact/suggest-compact.sh`, `tools/scripts/tests/local_temp_safety.test.js` |
|
|
|
|
|
| 31 | obsolete/not reproducible on current HEAD | `sync_recommended_skills.sh` now preserves symlinks with `cp -RP` and avoids the destructive glob-delete pattern called out in the original report. | `tools/scripts/sync_recommended_skills.sh`, `tools/scripts/tests/repo_hygiene_security.test.js` |
|
|
|
|
|
| 32 | obsolete/not reproducible on current HEAD | `skills_manager.py` now resolves candidate paths relative to the intended base directory and rejects traversal attempts. | `tools/scripts/skills_manager.py`, `tools/scripts/tests/test_skills_manager_security.py` |
|
|
|
|
|
| 33 | obsolete/not reproducible on current HEAD | The Office unpack helpers now validate archive members and reject traversal/symlink-style entries before extraction. | `skills/docx-official/ooxml/scripts/unpack.py`, `skills/pptx-official/ooxml/scripts/unpack.py`, `tools/scripts/tests/test_office_unpack_security.py` |
|
|
|
|
|
|
|
|
|
|
## Maintainer Notes
|
|
|
|
|
|
|
|
|
|
- Keep the 2026-03-15 markdown file and CSV as the historical baseline record.
|
|
|
|
|
- Keep the 2026-03-29 addendum as the intermediate transition note.
|
|
|
|
|
- Use this refresh when answering “what is still open right now?” for the
|
|
|
|
|
original 2026-03-15 finding set.
|
|
|
|
|
- If new findings are discovered later, start a fresh triage cycle rather than
|
|
|
|
|
mutating the historical baseline counts again.
|