Back to skill

Security audit

Slk

Security checks for vulnerabilities and agentic risk

Overview

This Slack skill is useful but needs Review because it extracts and caches your desktop Slack session credentials so an agent can read and act as you.

Install only on a personal macOS machine where you are comfortable granting an agent Slack access as you, including private messages and send actions. Prefer one-time Keychain Allow over Always Allow, remove the token cache when not needed, avoid shared or managed machines, and do not let agents follow the included publish/push/npm-token development steps without separate approval.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
AGENTS.md:93
Finding

Agent instructions require autonomous publishing and credential-backed deployment

Content
View full analysis
.npmrc npm publish rm .npmrc # Clean up — don't commit the token! ``` The `NPM_PUBLISH_TOKEN` env var is set in `~/.local/keys/env.sh`. ### 8. Update Local Moltbot Skill ```bash cp SKILL.md ~/moltbot/skills/slk/SKILL.md ``` ## Quick Reference: One-liner Full Deploy ```bash cd ~/Lab/slk # ... make changes ... npm version patch --no-git-tag-version git add -A && git commit -m "feat: description" && git push echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc && npm publish && rm .npmrc cp SKILL.md ~/moltbot/skills/slk/SKILL.md ``` ``` The same workflow is reinforced in `CLAUDE.md:15-29`, where publishing, pushing, and copying the Skill into persistent local agent storage are presented as mandatory feature-development steps. ### Technical Analysis `AGENTS.md` states that its “full loop” must be followed every time a change is made. The loop goes beyond development and testing: it instructs an AI coding agent to commit and push changes, retrieve or use an npm publication credential, publish a package, and overwrite a locally installed Skill. These actions are not necessary to complete a typical code modification or audit. They materially alter the agent's task by adding external side effects and privileged release operations without requiring explicit user confirmation. The npm token is written to a project-local `.npmrc`. Although the instructions subsequently remove that file, interruption, command failure, agent termination, or a malicious lifecycle script could leave or read the credential. The one-line form uses `&&`, so `.npmrc` is not deleted if `npm publish` fails. Copying `SKILL.md` i ...[truncated 1501 chars]
Remediation
View remediation
"$tmp_npmrc" NPM_CONFIG_USERCONFIG="$tmp_npmrc" npm publish ``` - Require an explicit human confirmation immediately before any `git push`, `npm publish`, or modification of `~/moltbot/skills`. - Apply the same corrections to both `AGENTS.md` and `CLAUDE.md`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
src/auth.js:188
Finding

Slack session token is persisted in plaintext without restrictive permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/auth.js:204
Finding

Slack credentials and cookie-decryption key are exposed through subprocess arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/auth.js:66
Finding

Predictable shared temporary files permit credential-data disclosure and symlink attacks

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (50)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · AGENTS.md (reported line 12)May include surrounding context.

md
├── bin/slk.js          # CLI entry point — command routing, help text, aliases
├── src/
│   ├── api.js          # Slack API wrapper — fetch, auth headers, pagination
│   ├── auth.js         # Credential extraction — Keychain, LevelDB, token cache
│   ├── commands.js     # All command implementations (read, send, saved, etc.)
│   └── drafts.js       # Draft-specific commands (create, list, drop)
├── package.json        # Version, bin mapping, metadata

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The instructions explicitly write an npm auth token into .npmrc, creating a plaintext credential file in the working directory. Even though the token comes from an environment variable, materializing it to disk increases exposure through backups, accidental commits, local malware, or interrupted cleanup.

Content

Scanner excerpt · AGENTS.md (reported line 102)May include surrounding context.

7. Publish to npm

bash
# Create .npmrc with publish token
echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc
npm publish
rm .npmrc   # Clean up — don't commit the token!

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · AGENTS.md (reported line 103)May include surrounding context.

bash
# Create .npmrc with publish token
echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc
npm publish
rm .npmrc   # Clean up — don't commit the token!

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The note that NPM_PUBLISH_TOKEN is set in ~/.local/keys/env.sh documents a specific secret source location, which meaningfully lowers the bar for credential targeting on a compromised system or by an over-privileged agent. Combined with the nearby instructions, it creates a clear path from secret location to on-disk token use.

Content

Scanner excerpt · AGENTS.md (reported line 105)May include surrounding context.

Create .npmrc with publish token

echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc npm publish rm .npmrc # Clean up — don't commit the token!

text

The `NPM_PUBLISH_TOKEN` env var is set in `~/.local/keys/env.sh`.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

This one-liner both materializes the npm token into .npmrc and immediately uses it in a chained command, making credential exposure and accidental execution more likely. Chaining also weakens opportunities for human review and can leave the secret file behind if later segments fail unexpectedly.

Content

Scanner excerpt · AGENTS.md (reported line 125)May include surrounding context.

... make changes ...

npm version patch --no-git-tag-version git add -A && git commit -m "feat: description" && git push echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc && npm publish && rm .npmrc cp SKILL.md ~/moltbot/skills/slk/SKILL.md

text

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The instruction to write ${NPM_PUBLISH_TOKEN} into .npmrc creates a plaintext credential file on disk, which may be read by other local processes, accidentally committed, backed up, or recovered if cleanup fails. Because this is framed as a routine release step, the skill normalizes unsafe credential handling and makes accidental secret exposure more likely.

Content

Scanner excerpt · CLAUDE.md (reported line 25)May include surrounding context.

md
6. Update `SKILL.md` (commands list)
7. `npm version patch --no-git-tag-version`
8. `git add -A && git commit -m "feat: ..." && git push`
9. `echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" > .npmrc && npm publish && rm .npmrc`
10. `cp SKILL.md ~/moltbot/skills/slk/SKILL.md`

## Testing

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The dedicated guidance to source NPM_PUBLISH_TOKEN from ~/.local/keys/env.sh and use the '.npmrc trick' documents a concrete secret retrieval and storage workflow that exposes credential material to local compromise, mishandling, and operational mistakes. In this skill's context, which already mentions auto-extracted Slack session credentials, the overall pattern reflects lax secret-handling practices and increases concern about broader credential exposure.

Content

Scanner excerpt · CLAUDE.md (reported line 50)May include surrounding context.

md
## npm Publish Token

`NPM_PUBLISH_TOKEN` env var from `~/.local/keys/env.sh`. Use `.npmrc` trick (create before publish, delete after).

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

This section states that the tool uses credentials already stored by the Slack desktop app and accesses macOS Keychain material to do so. In a personal automation utility this may be intentional, but in a skill designed for agents it materially lowers the barrier for credential theft and unauthorized account use because the agent can act as the user without separate authorization.

Content

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

md
`slk` uses the credentials already stored by the Slack desktop app. No OAuth flows, no manual token management.

### Keychain access prompt

On first run, macOS will show a Keychain dialog asking whether to allow access to "Slack Safe Storage":

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The documented flow reads and decrypts Slack cookies, scans LevelDB for xoxc- tokens, validates them, and reuses them automatically. This is classic credential-access behavior; if abused, it enables impersonation of the Slack user, broad message access, and stealthy persistence through cached tokens.

Content

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

md
### How it works

1. **Cookie decryption** — Reads the encrypted `d` cookie from Slack's SQLite cookie store (`Cookies` file). Decrypts it using the "Slack Safe Storage" key from the macOS Keychain via PBKDF2 + AES-128-CBC. Supports both direct-download and Mac App Store keychain account names.

2. **Token extraction** — Scans Slack's LevelDB storage (`Local Storage/leveldb/`) for `xoxc-` session tokens. Uses both direct regex scanning and a Python fallback for Snappy-compressed entries. The Slack data directory is auto-detected (direct download or App Store sandbox).

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly describes extracting Slack session credentials from macOS Keychain, cookies, and LevelDB rather than using Slack-supported OAuth. That gives the tool access as the logged-in user and normalizes credential harvesting from local stores, which is highly dangerous in an agent context because any compromised or over-privileged agent can silently inherit full Slack access.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The notes reinforce that the tool is built around Keychain access and Slack local storage path inspection. In the context of an agent skill, this makes the capability more dangerous because it is packaged as convenience automation while depending on sensitive credential-extraction primitives that can be repurposed for unauthorized access.

Content

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

md
## Notes

- **macOS only** — uses Keychain and Electron storage paths specific to macOS.
- **Both Slack variants supported** — works with the direct download (`~/Library/Application Support/Slack/`) and the Mac App Store version (`~/Library/Containers/com.tinyspeck.slackmacgap/.../Slack/`). The correct path is auto-detected at runtime.
- **Slack desktop app required** — must be installed and logged in. The app does not need to be running for cached tokens.
- **Zero dependencies** — uses only Node.js built-in modules (`crypto`, `fs`, `child_process`, `fetch`).

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a Slack messaging utility, but its authentication model relies on extracting Slack session material from local app storage, cookies, LevelDB, and macOS Keychain. That is a materially more sensitive behavior than ordinary messaging and could expose user session credentials or normalize credential-harvesting patterns under an innocuous description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as a Slack messaging utility, but its authentication model relies on extracting Slack session material from local app storage, cookies, LevelDB, and macOS Keychain. That is a materially more sensitive behavior than ordinary messaging and could expose user session credentials or normalize credential-harvesting patterns under an innocuous description.

Content

No source excerpt is available for this finding.

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 · AGENTS.md (reported line 140)May include surrounding context.

If auth fails (token rotated, Slack logged out):

bash
rm ~/.local/slk/token-cache.json
slk auth

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 · SKILL.md (reported line 64)May include surrounding context.

If auth fails (token rotated, Slack logged out):

bash
rm ~/.local/slk/token-cache.json
slk auth

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Use of Keychain-backed secret extraction to recover Slack session material is a credential-access capability with direct account implications. A skill that can retrieve or facilitate retrieval of these secrets can be abused to impersonate the user, access private Slack data, and persist beyond a normal bot-scoped integration.

Content

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

md
## Limitations

- **macOS only** — uses Keychain + Electron storage paths
- **Session-based** — acts as your user, not a bot. Be mindful of what you send
- **Draft drop** may fail with `draft_has_conflict` if Slack has that conversation open
- **Session token** expires on logout — keep Slack app running or rely on cached token

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The implementation does not authenticate to Slack through a normal user-approved flow; it harvests session material directly from macOS Keychain, Slack cookies, and LevelDB storage. That behavior materially exceeds the declared CLI-based Slack interaction purpose and enables covert account access by reusing desktop session credentials.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The file comment explicitly describes extracting Slack credentials from Keychain, cookies, and LevelDB, which is strong evidence of credential access functionality. In the context of a Slack messaging skill, this is highly dangerous because it facilitates unauthorized recovery and reuse of the user's session secrets.

Content

Scanner excerpt · src/auth.js (reported line 4)May include surrounding context.

js
/**
 * Slack auth — extracts session credentials from the Slack desktop app on macOS.
 *
 * 1. Keychain → "Slack Safe Storage" password
 * 2. Cookies SQLite → encrypted `d` cookie → AES-128-CBC decrypt
 * 3. LevelDB files → `xoxc-` token (string scan)
 */

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The getKeychainKey function is specifically designed to query the macOS Keychain for Slack Safe Storage secrets across multiple account names. Accessing these secrets allows subsequent decryption of protected Slack data, enabling session theft and impersonation.

Content

Scanner excerpt · src/auth.js (reported line 45)May include surrounding context.

js
let cachedCreds = null;

function getKeychainKey() {
  // Mac App Store Slack uses account "Slack App Store Key", direct download uses "Slack" or "Slack Key"
  const accounts = SLACK_DIR === SLACK_DIR_APPSTORE
    ? ["Slack App Store Key", "Slack Key", "Slack"]

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This code actively extracts secrets from local protected storage, decrypts them, and iterates candidate tokens until one validates. That is credential harvesting behavior, not a necessary or proportionate mechanism for checking messages, and it could let the skill impersonate the user in Slack.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill accesses macOS Keychain material associated with Slack without any user-facing disclosure or consent flow. Silent access to protected local secrets is dangerous because it bypasses user expectations and is a common precursor to credential theft and account takeover.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This specific line is only an error message referring to the Keychain, not the credential-access action itself. While it is part of a malicious credential-harvesting module, the line alone does not introduce additional exploitability beyond the surrounding implementation.

Content

Scanner excerpt · src/auth.js (reported line 62)May include surrounding context.

js
} catch {}
  }

  console.error("Could not find Slack Safe Storage key in Keychain.");
  process.exit(1);
}

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

This line derives an AES key from the Slack Safe Storage secret using PBKDF2 so the code can decrypt the encrypted Slack cookie. That directly operationalizes credential theft by converting protected local secrets into reusable session material.

Content

Scanner excerpt · src/auth.js (reported line 85)May include surrounding context.

js
}

    const data = encrypted.subarray(3);
    const aesKey = pbkdf2Sync(getKeychainKey(), "saltysalt", 1003, 16, "sha1");
    const iv = Buffer.alloc(16, " ");

    // Decrypt via openssl using spawnSync for clean binary output

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill writes recovered Slack tokens to disk in a local cache file without any visible consent, warning, or protection controls. Persisting stolen or sensitive session credentials increases the window of compromise and exposes them to reuse by other local processes or future exfiltration.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code sends harvested bearer tokens and decrypted session cookies to Slack's API to test which stolen credentials are valid, all without user awareness. This confirms usable credentials for impersonation and normalizes unauthorized access as part of runtime behavior.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/auth.js:54