Low Risk — Risk Score 18/100
Last scan:2 days ago Rescan
18 /100
gstack
Fast headless browser for QA testing and site dogfooding. Navigate URLs, interact with elements, verify page state, diff before/after actions, take annotated screenshots, test forms and uploads.
This is a legitimate headless browser QA testing tool with no malicious behavior. All flagged IOCs are either documented user-facing instructions (bun installer, uninstall script) or test fixtures. No hidden credential theft, data exfiltration, or covert execution was found.
Skill Namegstack
Duration62.9s
Enginepi
Safe to install
No action needed. The skill is safe for use. Minor documentation gaps around filesystem WRITE and cookie-import-browser capability should be addressed in allowed-tools.

Findings 4 items

Severity Finding Location
Low
allowed-tools metadata is incomplete
The root SKILL.md declares only 'Bash' and 'Read' in allowed-tools, but the skill performs filesystem WRITE operations (session file management in ~/.gstack/), uses subprocess for cookie-import-browser, and manages browser state. While these operations are benign, they should be reflected in allowed-tools for accuracy.
allowed-tools:
  - Bash
  - Read
  - AskUserQuestion
→ Update allowed-tools to include Write capability and document cookie-import-browser access.
SKILL.md:7
Low
Subprocess commands not documented in skill preamble
The skill spawns subprocesses for 'git' (git rev-parse, git remote), 'security' (keychain), and 'bun' without explicit documentation in SKILL.md. While these are standard CLI tool behaviors, declaring them improves transparency.
const proc = Bun.spawnSync(['git', 'rev-parse', '--show-toplevel'], {...})
→ Add a brief note in SKILL.md that the skill uses git and system keychain access as part of its core functionality.
browse/src/config.ts:30
Info
Hardcoded test credentials are test fixtures only
browse/test/cookie-import-browser.test.ts contains 'test-keychain-password' as a test fixture. The file contains extensive documentation explaining this is a synthetic test key with no relation to production credentials. This is standard practice for testing cryptographic code.
const TEST_PASSWORD = 'test-keychain-password';
→ No action needed. Test fixtures are appropriately documented.
browse/test/cookie-import-browser.test.ts:8
Info
IP address strings are version metadata, not network indicators
retro/SKILL.md:399 contains '1.16.0.0' and '1.16.1.0' which appear in a changelog-style version range summary. These are version numbers presented in IP-dot notation, not actual network addresses.
"version_range": ["1.16.0.0", "1.16.1.0"]
→ No action needed. These are version identifiers, not network indicators.
retro/SKILL.md:399
ResourceDeclaredInferredStatusEvidence
Shell WRITE WRITE ✓ Aligned SKILL.md:allowed-tools includes 'Bash'
Filesystem READ WRITE ✓ Aligned Creates ~/.gstack/sessions/ files and manages state dirs. Declared as 'Read' but…
Network NONE READ ✓ Aligned Subprocess calls (git, security) resolve to local operations. Uses HTTPS for Pla…
Browser NONE WRITE ✓ Aligned cookie-import-browser command imports cookies from Chromium-based browsers. Decl…
2 Critical 4 High 39 findings
💀
Critical Dangerous Command 危险 Shell 命令
curl -fsSL https://bun.sh/install | bash
README.md:629
💀
Critical Dangerous Command 危险 Shell 命令
rm -rf ~
README.md:641
🔑
High API Key 疑似硬编码凭证
password = "test-keychain-password"
browse/test/cookie-import-browser.test.ts:8
🔑
High API Key 疑似硬编码凭证
PASSWORD = 'test-keychain-password'
browse/test/cookie-import-browser.test.ts:25
📡
High IP Address 硬编码 IP 地址
1.16.0.0
retro/SKILL.md:399
📡
High IP Address 硬编码 IP 地址
1.16.1.0
retro/SKILL.md:399
🔗
Medium External URL 外部 URL
https://playwright.dev/
BROWSER.md:25
🔗
Medium External URL 外部 URL
https://staging.myapp.com
BROWSER.md:31
🔗
Medium External URL 外部 URL
https://conductor.build
CONTRIBUTING.md:228
🔗
Medium External URL 外部 URL
https://docs.anthropic.com/en/docs/claude-code
README.md:5
🔗
Medium External URL 外部 URL
https://git-scm.com/
README.md:102
🔗
Medium External URL 外部 URL
https://x.com/garrytan
README.md:147
🔗
Medium External URL 外部 URL
https://www.ycombinator.com/
README.md:147
🔗
Medium External URL 外部 URL
https://greptile.com
README.md:345
🔗
Medium External URL 外部 URL
https://staging.myapp.com/signup
README.md:427
🔗
Medium External URL 外部 URL
https://staging.myapp.com/dashboard
README.md:437
🔗
Medium External URL 外部 URL
https://staging.myapp.com/settings/billing
README.md:444
🔗
Medium External URL 外部 URL
https://staging.myapp.com/api/health
README.md:451
🔗
Medium External URL 外部 URL
https://bun.sh/install
README.md:629
🔗
Medium External URL 外部 URL
https://app.example.com/login
SKILL.md:121
🔗
Medium External URL 外部 URL
https://yourapp.com
SKILL.md:140
🔗
Medium External URL 外部 URL
https://app.example.com/new-feature
SKILL.md:153
🔗
Medium External URL 外部 URL
https://app.example.com/upload
SKILL.md:203
🔗
Medium External URL 外部 URL
https://app.example.com/form
SKILL.md:213
🔗
Medium External URL 外部 URL
https://staging.app.com
SKILL.md:259
🔗
Medium External URL 外部 URL
https://prod.app.com
SKILL.md:259
🔗
Medium External URL 外部 URL
https://app.example.com
SKILL.md:266
🔗
Medium External URL 外部 URL
https://app.com/login
browse/SKILL.md:121
🔗
Medium External URL 外部 URL
http://127.0.0.1:9470
browse/test/cookie-picker-routes.test.ts:40
🔗
Medium External URL 外部 URL
http://127.0.0.1:9450
browse/test/cookie-picker-routes.test.ts:62
🔗
Medium External URL 外部 URL
https://external.com/link
browse/test/fixtures/basic.html:18
🔗
Medium External URL 外部 URL
https://external.com
browse/test/fixtures/snapshot.html:21
🔗
Medium External URL 外部 URL
https://myapp.com
qa/SKILL.md:117
🔗
Medium External URL 外部 URL
https://claude.com/claude-code
ship/SKILL.md:477
📧
Info Email 邮箱地址
[email protected]
SKILL.md:268
📧
Info Email 邮箱地址
[email protected]
browse/SKILL.md:123
📧
Info Email 邮箱地址
[email protected]
browse/src/config.ts:128
📧
Info Email 邮箱地址
[email protected]
browse/test/fixtures/forms.html:19
📧
Info Email 邮箱地址
[email protected]
browse/test/fixtures/qa-eval-spa.html:75

File Tree

88 files · 921.6 KB · 23226 lines
TypeScript 42f · 14629L Markdown 24f · 7784L HTML 13f · 554L JSON 6f · 188L Ruby 3f · 71L
├─ 📁 browse
│ ├─ 📁 src
│ │ ├─ 📜 browser-manager.ts TypeScript 466L · 14.9 KB
│ │ ├─ 📜 buffers.ts TypeScript 137L · 4.2 KB
│ │ ├─ 📜 cli.ts TypeScript 326L · 10.8 KB
│ │ ├─ 📜 commands.ts TypeScript 107L · 7.7 KB
│ │ ├─ 📜 config.ts TypeScript 150L · 4.6 KB
│ │ ├─ 📜 cookie-import-browser.ts TypeScript 417L · 15.3 KB
│ │ ├─ 📜 cookie-picker-routes.ts TypeScript 207L · 7.5 KB
│ │ ├─ 📜 cookie-picker-ui.ts TypeScript 541L · 16.4 KB
│ │ ├─ 📜 find-browse.ts TypeScript 56L · 1.6 KB
│ │ ├─ 📜 meta-commands.ts TypeScript 273L · 9.7 KB
│ │ ├─ 📜 read-commands.ts TypeScript 308L · 11.1 KB
│ │ ├─ 📜 server.ts TypeScript 364L · 13.3 KB
│ │ ├─ 📜 snapshot.ts TypeScript 397L · 14.8 KB
│ │ └─ 📜 write-commands.ts TypeScript 312L · 11.2 KB
│ ├─ 📁 test
│ │ ├─ 📁 fixtures
│ │ │ ├─ 📄 basic.html HTML 33L · 914 B
│ │ │ ├─ 📄 cursor-interactive.html HTML 22L · 883 B
│ │ │ ├─ 📄 dialog.html HTML 15L · 603 B
│ │ │ ├─ 📄 empty.html HTML 2L · 43 B
│ │ │ ├─ 📄 forms.html HTML 55L · 1.8 KB
│ │ │ ├─ 📄 qa-eval-checkout.html HTML 108L · 4.2 KB
│ │ │ ├─ 📄 qa-eval-spa.html HTML 98L · 3.2 KB
│ │ │ ├─ 📄 qa-eval.html HTML 51L · 1.7 KB
│ │ │ ├─ 📄 responsive.html HTML 49L · 1.4 KB
│ │ │ ├─ 📄 snapshot.html HTML 55L · 1.5 KB
│ │ │ ├─ 📄 spa.html HTML 24L · 638 B
│ │ │ ├─ 📄 states.html HTML 17L · 567 B
│ │ │ └─ 📄 upload.html HTML 25L · 849 B
│ │ ├─ 📜 commands.test.ts TypeScript 1753L · 63.4 KB
│ │ ├─ 📜 config.test.ts TypeScript 220L · 9.6 KB
│ │ ├─ 📜 cookie-import-browser.test.ts TypeScript 397L · 16.1 KB
│ │ ├─ 📜 cookie-picker-routes.test.ts TypeScript 205L · 7.4 KB
│ │ ├─ 📜 find-browse.test.ts TypeScript 24L · 782 B
│ │ ├─ 📜 gstack-config.test.ts TypeScript 125L · 4.7 KB
│ │ ├─ 📜 gstack-update-check.test.ts TypeScript 467L · 19.3 KB
│ │ ├─ 📜 snapshot.test.ts TypeScript 467L · 19.7 KB
│ │ └─ 📜 test-server.ts TypeScript 57L · 1.7 KB
│ └─ 📝 SKILL.md Markdown 311L · 12.7 KB
├─ 📁 document-release
│ └─ 📝 SKILL.md Markdown 437L · 17.9 KB
├─ 📁 gstack-upgrade
│ └─ 📝 SKILL.md Markdown 201L · 6.5 KB
├─ 📁 plan-ceo-review
│ └─ 📝 SKILL.md Markdown 572L · 36.9 KB
├─ 📁 plan-eng-review
│ └─ 📝 SKILL.md Markdown 263L · 16.6 KB
├─ 📁 qa
│ ├─ 📁 references
│ │ └─ 📝 issue-taxonomy.md Markdown 85L · 3.5 KB
│ ├─ 📁 templates
│ │ └─ 📝 qa-report-template.md Markdown 110L · 2.5 KB
│ └─ 📝 SKILL.md Markdown 618L · 23.0 KB
├─ 📁 qa-only
│ └─ 📝 SKILL.md Markdown 453L · 17.9 KB
├─ 📁 retro
│ └─ 📝 SKILL.md Markdown 550L · 23.3 KB
├─ 📁 review
│ ├─ 📝 checklist.md Markdown 132L · 7.7 KB
│ ├─ 📝 greptile-triage.md Markdown 220L · 8.1 KB
│ ├─ 📝 SKILL.md Markdown 229L · 11.5 KB
│ └─ 📝 TODOS-format.md Markdown 62L · 1.6 KB
├─ 📁 scripts
│ ├─ 📜 dev-skill.ts TypeScript 82L · 2.4 KB
│ ├─ 📜 eval-compare.ts TypeScript 96L · 3.0 KB
│ ├─ 📜 eval-list.ts TypeScript 116L · 3.5 KB
│ ├─ 📜 eval-summary.ts TypeScript 187L · 6.4 KB
│ ├─ 📜 eval-watch.ts TypeScript 172L · 5.4 KB
│ ├─ 📜 gen-skill-docs.ts TypeScript 573L · 22.4 KB
│ └─ 📜 skill-check.ts TypeScript 114L · 3.8 KB
├─ 📁 setup-browser-cookies
│ └─ 📝 SKILL.md Markdown 155L · 6.4 KB
├─ 📁 ship
│ └─ 📝 SKILL.md Markdown 497L · 22.6 KB
├─ 📁 test
│ ├─ 📁 fixtures
│ │ ├─ 📋 eval-baselines.json JSON 7L · 388 B
│ │ ├─ 📋 qa-eval-checkout-ground-truth.json JSON 43L · 1.6 KB
│ │ ├─ 📋 qa-eval-ground-truth.json JSON 43L · 1.5 KB
│ │ ├─ 📋 qa-eval-spa-ground-truth.json JSON 43L · 1.6 KB
│ │ ├─ 📄 review-eval-enum-diff.rb Ruby 30L · 986 B
│ │ ├─ 📄 review-eval-enum.rb Ruby 27L · 759 B
│ │ └─ 📄 review-eval-vuln.rb Ruby 14L · 406 B
│ ├─ 📁 helpers
│ │ ├─ 📜 eval-store.test.ts TypeScript 548L · 19.8 KB
│ │ ├─ 📜 eval-store.ts TypeScript 681L · 23.1 KB
│ │ ├─ 📜 llm-judge.ts TypeScript 130L · 4.2 KB
│ │ ├─ 📜 observability.test.ts TypeScript 283L · 9.9 KB
│ │ ├─ 📜 session-runner.test.ts TypeScript 96L · 3.7 KB
│ │ ├─ 📜 session-runner.ts TypeScript 334L · 10.4 KB
│ │ └─ 📜 skill-parser.ts TypeScript 206L · 5.6 KB
│ ├─ 📜 gen-skill-docs.test.ts TypeScript 321L · 12.7 KB
│ ├─ 📜 skill-e2e.test.ts TypeScript 1675L · 65.6 KB
│ ├─ 📜 skill-llm-eval.test.ts TypeScript 440L · 17.4 KB
│ ├─ 📜 skill-parser.test.ts TypeScript 179L · 5.3 KB
│ └─ 📜 skill-validation.test.ts TypeScript 620L · 22.8 KB
├─ 📝 ARCHITECTURE.md Markdown 355L · 20.0 KB
├─ 📝 BROWSER.md Markdown 258L · 15.8 KB
├─ 📝 CHANGELOG.md Markdown 295L · 25.3 KB
├─ 📝 CLAUDE.md Markdown 145L · 7.3 KB
├─ 📋 conductor.json JSON 6L · 87 B
├─ 📝 CONTRIBUTING.md Markdown 294L · 12.9 KB
├─ 📋 package.json JSON 46L · 1.6 KB
├─ 📝 README.md Markdown 659L · 30.6 KB
├─ 📝 SKILL.md Markdown 443L · 16.1 KB
└─ 📝 TODOS.md Markdown 440L · 14.7 KB

Dependencies 2 items

PackageVersionSourceKnown VulnsNotes
playwright ^1.58.2 npm No Pinned to ^1.58.2 with caret range. Could be more restrictive but major versions match.
diff ^7.0.0 npm No Standard text diffing library, minimal attack surface.

Security Positives

✓ No credential exfiltration detected — cookie-import-browser decrypts cookies locally and passes them to Playwright only
✓ Parameterised SQL queries prevent injection attacks in cookie-import-browser
✓ eval command restricts file paths to /tmp or cwd only, preventing arbitrary file reads
✓ Sensitive HTTP headers (authorization, cookies, API keys) are automatically redacted in logs
✓ Key derivation keys cached only in-process memory, not persisted to disk
✓ Bearer token authentication protects the browser server from unauthorized access
✓ Profile name validation prevents path traversal attacks in cookie-import-browser
✓ Proper error handling with user-friendly messages for all failure modes
✓ Production code contains no hardcoded credentials — only test fixtures have test passwords
✓ Uses HTTPS for Playwright browser binary downloads
✓ Subprocess calls use allowlist approach (git, security, bun only) rather than arbitrary command execution