Back to skill

Security audit

Office Hour Legends

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent coaching purpose, but it handles sensitive meeting and private-forum data and includes a real local code-injection bug plus risky credential-handling guidance.

Review before installing. Use transcript review only for meetings you are allowed to process, avoid committing or syncing saved session docs, fix or avoid the Fathom recording-ID injection path, and do not enable Bookface unless you have reviewed and pinned that third-party script and are comfortable with how it handles YC credentials and cached sessions.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fathom-get-transcript.sh:11
Finding

Recording ID Allows Arbitrary Python Code Injection

Content
View full analysis
}" API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}" # Fetch recent meetings with transcripts and filter for the requested one curl -sS "https://api.fathom.ai/external/v1/meetings?limit=100&include_summary=true&include_transcript=true" \ -H "X-Api-Key: ${API_KEY}" \ | python3 -c " import json, sys data = json.load(sys.stdin) target = int('${RECORDING_ID}') for item in data.get('items', []): if item.get('recording_id') == target: print(json.dumps(item, indent=2)) sys.exit(0) print(json.dumps({'error': 'Meeting not found', 'recording_id': target})) sys.exit(1) " ``` ### Technical Analysis `RECORDING_ID` is obtained directly from the first command-line argument and interpolated into a Python program passed to `python3 -c`. Shell quoting does not make the value safe for inclusion in Python source code. An attacker-controlled value can close the Python string and `int()` expression, append arbitrary Python statements, and comment out the remaining generated source. For example, a value shaped like: ```text 1'); __import__('os').system('id'); # ``` would transform the relevant generated source into the equivalent of: ```python target = int('1'); __import__('os').system('id'); #') ``` The injected statement is then evaluated by the local Python interpreter. The use of `set -euo pipefail` does not prevent this because the injection occurs within syntactically valid Python executed as part of the pipeline. ### Attack Path 1. An attacker supplies, or causes the Agent to extract, a malicious value as a Fathom recording ID. 2. The transcript workflow invokes: ```bash bash "$_SKILL_DIR/scripts/fathom-get ...[truncated 1205 chars]
Remediation
View remediation
}" API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}" if [[ ! "$RECORDING_ID" =~ ^[0-9]+$ ]]; then printf 'Invalid recording ID: expected digits only\n' >&2 exit 2 fi curl -sS \ "https://api.fathom.ai/external/v1/meetings?limit=100&include_summary=true&include_transcript=true" \ -H "X-Api-Key: ${API_KEY}" \ | python3 -c ' import json import sys data = json.load(sys.stdin) target = int(sys.argv[1]) for item in data.get("items", []): if item.get("recording_id") == target: print(json.dumps(item, indent=2)) sys.exit(0) print(json.dumps({"error": "Meeting not found", "recording_id": target})) sys.exit(1) ' "$RECORDING_ID" ``` This separates executable Python source from untrusted input and removes the injection primitive. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:345
Finding

Unpinned Third-Party Bookface Integration Handles Private Account Credentials

Content
View full analysis
~/.bookface_credentials <<'EOF' BOOKFACE_USERNAME="your-yc-username" BOOKFACE_PASSWORD="your-yc-password" EOF chmod 600 ~/.bookface_credentials ``` The documentation confirms that the dependency performs form-based authentication and stores session material in temporary files: ```markdown - **No OAuth.** The script does form-based login: scrapes a CSRF token from `account.ycombinator.com`, POSTs your creds to `/sign_in`, and extracts an Algolia API key from your logged-in home page. - **Session cache.** The Algolia key is cached at `/tmp/bookface_algolia_key` for ~12h, so you only pay the login cost once per session. Cookies live at `/tmp/bookface_cookies`. - **Credentials on disk.** `~/.bookface_credentials` is a plaintext shell file. `chmod 600` it. Don't commit it. Don't sync it into a cloud drive. ``` The Skill automatically detects and executes the installed script: ```bash if [ -x "$HOME/.claude/skills/bookface/bookface-search.sh" ]; then _BOOKFACE=1 else _BOOKFACE=0 fi ``` ```bash ~/.claude/skills/bookface/bookface-search.sh "" ``` ### Technical Analysis The project does not pin `bookface-search` to a reviewed commit, signed tag, immutable release artifact, or verified checksum. A ...[truncated 2665 chars]
Remediation
View remediation
``` 2. Publish and verify a cryptographic checksum or signature for the reviewed artifact before execution. 3. Do not silently execute the integration merely because an executable file exists. Require explicit user consent before the first Bookface access and clearly identify the third-party component that will run. 4. Prefer OAuth or a narrowly scoped, revocable API token. Avoid providing a reusable YC account password to automation whenever an alternative authentication mechanism is available. 5. Do not store credentials as sourceable shell code. If credentials must be stored, use an operating-system credential manager or secret store and retrieve them only for the duration of the request. 6. Create temporary cookie and key files with unpredictable names and restrictive permissions, such as through `mktemp` under a user-private directory. Remove them reliably with a shell `trap`. 7. Execute the integration with a minimized environment and only the permissions it needs. Do not expose unrelated Agent secrets or broad filesystem access. 8. Document a dependency-review and update procedure. New upstream revisions should be inspected and pinned before deployment rather than accepted automatically. 9. Consider vendoring a minimal reviewed client implementation if Bookface integration is essential, subject to YC's authentication and access policies. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (21)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · README.md (reported line 382)May include surrounding context.

md
form, the script will break until upstream updates it. Legends skip
  Bookface silently when the script errors - sessions still run.
- **Force re-auth.** If searches start failing, delete the cached files:
  `rm -f /tmp/bookface_algolia_key /tmp/bookface_cookies`.

### When it doesn't run

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · personas/justin-kan/persona.md (reported line 68)May include surrounding context.

md
## Cadence
- Casual, conversational, often vulnerable. Sounds like a friend, not a partner at a fund.
- Will drop into a serious personal aside without warning and then come back out.
- Comfortable with silence and with admitting he doesn't know.
- Short-to-medium sentences. Not quite Sam's clipped style, not quite PG's essay mode. More like a podcast guest who's thought about this a lot.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · personas/justin-kan/voice.md (reported line 5)May include surrounding context.

md
## Cadence
- Casual, conversational, often vulnerable. Sounds like a friend, not a partner at a fund.
- Will drop into a serious personal aside without warning and then come back out.
- Comfortable with silence and with admitting he doesn't know.
- Short-to-medium sentences. Not quite Sam's clipped style, not quite PG's essay mode. More like a podcast guest who's thought about this a lot.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/fathom-get-transcript.sh (reported line 15)May include surrounding context.

sh
API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}"

# Fetch recent meetings with transcripts and filter for the requested one
curl -sS "https://api.fathom.ai/external/v1/meetings?limit=100&include_summary=true&include_transcript=true" \
  -H "X-Api-Key: ${API_KEY}" \
  | python3 -c "
import json, sys

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly encourages pulling and analyzing full meeting transcripts from Fathom, including every speaker and line, but does not prominently warn that these transcripts may contain highly sensitive business, personal, or third-party information. In an agent skill context, that omission can cause users to send confidential meeting data into an automated workflow without understanding retention, exposure, or downstream handling risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README says session docs are saved as markdown files after transcript review and office-hours sessions, but it does not warn that those files may persist sensitive startup strategy, investor/customer conversations, and transcript-derived notes on disk. That increases the chance of unintended disclosure through local backups, source-control commits, shared folders, or multi-user machines.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 171)May include surrounding context.

md
2. **Full read.** The legend reads the entire transcript, summary, and action items.
3. **Timestamped feedback.** The legend walks through the meeting: what you did
   well, what you fumbled, and investor/customer signals you may have missed.
4. **Rewrite suggestions.** For the weakest moments, the legend writes what they
   would have said instead.
5. **Live session.** You go back and forth with the legend to sharpen your pitch,
   rework answers, or pivot into a broader office-hours discussion.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 362)May include surrounding context.

BOOKFACE_USERNAME="your-yc-username" BOOKFACE_PASSWORD="your-yc-password" EOF chmod 600 ~/.bookface_credentials

text

Restart Claude Code. Legends auto-detect Bookface and use it when the

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 377)May include surrounding context.

md
for ~12h, so you only pay the login cost once per session. Cookies live
  at `/tmp/bookface_cookies`.
- **Credentials on disk.** `~/.bookface_credentials` is a plaintext shell
  file. `chmod 600` it. Don't commit it. Don't sync it into a cloud drive.
- **Brittle to YC changes.** If YC adds 2FA, captcha, or changes the sign-in
  form, the script will break until upstream updates it. Legends skip
  Bookface silently when the script errors - sessions still run.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest advertises transcript review at a high level, but the skill actually enumerates meetings and fetches transcripts via external Fathom scripts, which expands the data access surface beyond what a user may reasonably expect. That gap matters because the workflow can access meeting metadata and transcript content containing sensitive business or personal information without an explicit upfront disclosure in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The transcript review workflow handles meeting recordings, transcripts, and invitee metadata, but the skill description does not warn users about these privacy-sensitive operations. In context, this is dangerous because office-hours and investor/customer calls often contain confidential business strategy and personal data, and users may not realize the skill will enumerate and process that information.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger phrases are broad enough to match common requests like 'review my pitch' or 'review my transcript,' which can cause the skill to activate in contexts where the user did not intend persona simulation, transcript access, or external research. Overbroad activation increases the chance of surprising data access and unintended execution of side-effecting workflows.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The allowed tool set includes persistent modification capabilities such as Write and Edit, plus Bash and web access, enabling the skill to save or alter local files during a session. In this skill's context, that is material because it can store sensitive startup notes and transcript-derived content, and the persistence is not clearly surfaced to the user up front.

Content

Scanner excerpt · SKILL.md (reported line 18)May include surrounding context.

md
- Read
  - Grep
  - Glob
  - Write
  - Edit
  - AskUserQuestion
  - WebSearch

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 87)May include surrounding context.

md
If no legend was named, use AskUserQuestion with the available legends as
options (read from `personas/`, skip folders starting with `_`). If the named
legend doesn't exist, list available ones and point the user at
`personas/_TEMPLATE/` to create a new one.

## Phase 2: Load the legend

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The stated purpose is to simulate YC-style office hours through a selected legend and review transcripts. Adding private Bookface research over forum, companies, vendors, deals, and articles expands the skill into broader external intelligence gathering that is not clearly justified by the manifest description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest focuses on adopting a legend persona and optionally reviewing Fathom transcripts. Pulling public HN search, comments, front-page analysis, and thread reading introduces a separate market-research capability that is not explicitly part of the described skill purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill persists design/session documents to the user's filesystem, but this write behavior is not disclosed in the manifest description. Undisclosed persistence is risky because users may reveal confidential startup, investor, or meeting information that then remains stored locally without clear consent or retention expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This shell script performs a network request to the Fathom API with include_transcript=true, which retrieves potentially sensitive meeting transcript data. Although the comments describe usage and required credentials, there is no user-facing warning, confirmation, or disclosure that transcript content and the API key will be sent in an external HTTP request.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fathom-get-transcript.sh (reported line 15)May include surrounding context.

sh
LIMIT="${1:-20}"
API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}"

curl -sS "https://api.fathom.ai/external/v1/meetings?limit=${LIMIT}&include_summary=true&include_transcript=false" \
  -H "X-Api-Key: ${API_KEY}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fathom-list-meetings.sh (reported line 11)May include surrounding context.

sh
LIMIT="${1:-20}"
API_KEY="${FATHOM_API_KEY:?Missing FATHOM_API_KEY environment variable}"

curl -sS "https://api.fathom.ai/external/v1/meetings?limit=${LIMIT}&include_summary=true&include_transcript=false" \
  -H "X-Api-Key: ${API_KEY}"

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The persona explicitly prohibits certain wording and mandates a particular style, including 'No AI-sounding language' and 'No em dashes.' This is a natural-language constraint that forces output style regardless of user preference, which can conflict with language/locale policy expectations when no opt-in or exception is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.