Back to skill

Security audit

CRM Kit

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent hosted CRM skill, but it asks agents to persist a long-lived bearer token in generic memory while enabling broad CRM data changes.

Install only if you trust crmkit.ai with your CRM data and are comfortable giving the agent authority to read and change records in the selected workspace. Store any bearer token only in a secure credential manager, do not put it in ordinary chat memory or transcripts, and review/revoke tokens regularly with the documented token endpoints.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:48
Finding

Unsafe Persistence of a Long-Lived Bearer Token in Unspecified Agent Memory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 48–55
Vulnerability Type: Insecure credential storage guidance
Risk Level: Medium

Vulnerable Snippet

text
     -> returns a token. SAVE IT. Send it as Authorization: Bearer <token> from
        now on. If you can persist it in memory, do so; otherwise ask the user
        to keep it for next session.
   Set "token_name" to label this session - e.g. your client ("ChatGPT",
   "Claude", "Cursor") or its purpose. It appears in GET /tokens so the user can
   recognize and revoke sessions. Optional; defaults to "default".
On any 401 (auth_required / invalid_token / token_expired), repeat this flow.
Tokens are long-lived but expire after a period of inactivity (each use renews
them), so a token in regular use keeps working; an idle one eventually dies.

Technical Analysis

The Skill tells the agent to save a bearer token and, where possible, persist it in unspecified “memory.” It does not require a dedicated encrypted credential store, define access controls, prohibit storage in prompts or transcripts, or require authorization-header redaction from logs.

A bearer token grants access based solely on possession. Because the token is long-lived and each use renews its inactivity period, disclosure can provide an attacker with sustained authenticated access. Generic agent memory may be included in conversation context, retained in logs, exposed to other Skills or integrations, or displayed in exported transcripts. It is therefore unsuitable for storing reusable authentication secrets unless backed by a purpose-built secret-management mechanism.

Sending the bearer token to https://api.crmkit.ai is necessary for the declared hosted CRM functionality and is not itself an undisclosed exfiltration path. The vulnerability is the recommendation to persist that credential without secure-storage constraints.

Attack Path

  1. A user completes the email OTP flow, and the CRM API ret ...[truncated 1600 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the instruction to persist the token in generic agent memory with a requirement to use an OS keychain, encrypted vault, or platform-provided credential manager.
  2. Explicitly prohibit placing bearer tokens in model prompts, long-term semantic memory, chat transcripts, plaintext files, telemetry, exception messages, or application logs.
  3. Redact Authorization headers and token values from tool output, debugging data, and user-visible responses.
  4. Prefer short-lived, narrowly scoped access tokens. If session continuity is required, use a separately protected, bounded refresh token with rotation and reuse detection.
  5. Bind tokens to the minimum required workspace and role, and introduce finer-grained scopes where supported.
  6. Provide clear token-revocation instructions and advise immediate revocation through GET /tokens and DELETE /tokens/{id} after suspected exposure.
  7. Avoid automatically renewing sessions indefinitely. Enforce an absolute token lifetime in addition to inactivity expiration.
  8. Assign descriptive session names and periodically review and revoke stale or unrecognized sessions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (11)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 84)May include surrounding context.

md
GET    /workspaces/{id}/members     members + pending invites
POST   /workspaces/{id}/invites     add someone  {"email":"x@acme.com","role":"member"} (admin only)
POST   /workspaces/{id}/members/{userId}/role   change role {"role":"admin"|"member"} (admin only)
DELETE /workspaces/{id}/members/{userId}   remove a member (admin only)
DELETE /workspaces/{id}               delete the workspace + all its data (admin only)

Roles are "admin" and "member". Admins manage membership; members operate the

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 85)May include surrounding context.

md
POST   /workspaces/{id}/invites     add someone  {"email":"x@acme.com","role":"member"} (admin only)
POST   /workspaces/{id}/members/{userId}/role   change role {"role":"admin"|"member"} (admin only)
DELETE /workspaces/{id}/members/{userId}   remove a member (admin only)
DELETE /workspaces/{id}               delete the workspace + all its data (admin only)

Roles are "admin" and "member". Admins manage membership; members operate the
CRM. Invites are by email: the invited person is emailed sign-in instructions

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 129)May include surrounding context.

md
GET    /readyz                      readiness probe - checks the database (no auth)
GET    /whoami                      identity + current workspace behind the token
GET    /tokens                      list your active tokens (sessions)
DELETE /tokens/{id}                 revoke one of your tokens (log out a session)

GET    /contacts?<filters>&search=&sort=&limit=&cursor=   list/query contacts (see QUERY)
POST   /contacts                    create OR update by email (upsert)  {"name":...,"email":...,"company_id":...,"stage":...,"tags":[...],"custom":{...}}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 135)May include surrounding context.

md
POST   /contacts                    create OR update by email (upsert)  {"name":...,"email":...,"company_id":...,"stage":...,"tags":[...],"custom":{...}}
GET    /contacts/{id}               fetch one contact
PATCH  /contacts/{id}               update fields
DELETE /contacts/{id}?confirm=      delete (two-step)
GET    /contacts/{id}/activities    activity log for a contact
POST   /contacts/{id}/activities    log  {"kind":"call|email|meeting|note|task","body":...}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 143)May include surrounding context.

md
POST   /companies                   create OR update by domain (upsert)  {"name":...,"domain":...,"custom":{...}}
GET    /companies/{id}              fetch one company
PATCH  /companies/{id}              update fields
DELETE /companies/{id}?confirm=     delete (two-step)

GET    /deals?<filters>&search=&sort=&limit=&cursor=      list/query deals (see QUERY)
POST   /deals                       create  {"title":...,"amount_cents":...,"currency":"USD","stage":...,"contact_id":...,"company_id":...}

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 149)May include surrounding context.

md
POST   /deals                       create  {"title":...,"amount_cents":...,"currency":"USD","stage":...,"contact_id":...,"company_id":...}
GET    /deals/{id}                  fetch one deal
PATCH  /deals/{id}                  update (e.g. {"stage":"won","status":"won"})
DELETE /deals/{id}?confirm=         delete (two-step)

GET    /reminders?days=&limit=      due/overdue follow-ups (contacts + deals due now; ?days=N looks ahead)
GET    /activities?contact=&deal=&limit=          recent activities

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 31)May include surrounding context.

md
MCP CONNECTOR (chat clients)
----------------------------
Besides this plain HTTP API, crmkit is also a Model Context Protocol server at
POST https://api.crmkit.ai/mcp, so you can add it as a connector in clients like ChatGPT and
Claude. Point the client at https://api.crmkit.ai/mcp and it will walk the standard OAuth
flow automatically: it registers itself (dynamic client registration), opens a
crmkit sign-in page where the user enters their email and pastes the emailed

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 32)May include surrounding context.

md
MCP CONNECTOR (chat clients)
----------------------------
Besides this plain HTTP API, crmkit is also a Model Context Protocol server at
POST https://api.crmkit.ai/mcp, so you can add it as a connector in clients like ChatGPT and
Claude. Point the client at https://api.crmkit.ai/mcp and it will walk the standard OAuth
flow automatically: it registers itself (dynamic client registration), opens a
crmkit sign-in page where the user enters their email and pastes the emailed

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 166)May include surrounding context.

md
MCP CONNECTOR (chat clients)
----------------------------
Besides this plain HTTP API, crmkit is also a Model Context Protocol server at
POST https://api.crmkit.ai/mcp, so you can add it as a connector in clients like ChatGPT and
Claude. Point the client at https://api.crmkit.ai/mcp and it will walk the standard OAuth
flow automatically: it registers itself (dynamic client registration), opens a
crmkit sign-in page where the user enters their email and pastes the emailed

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 169)May include surrounding context.

md
MCP CONNECTOR (chat clients)
----------------------------
Besides this plain HTTP API, crmkit is also a Model Context Protocol server at
POST https://api.crmkit.ai/mcp, so you can add it as a connector in clients like ChatGPT and
Claude. Point the client at https://api.crmkit.ai/mcp and it will walk the standard OAuth
flow automatically: it registers itself (dynamic client registration), opens a
crmkit sign-in page where the user enters their email and pastes the emailed

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

md
EXAMPLES (curl)
---------------
# begin login
curl -s -X POST https://api.crmkit.ai/auth/request -d '{"email":"you@example.com"}'

# create a contact (note the bearer token)
curl -s -X POST https://api.crmkit.ai/contacts \

Static analysis

No suspicious patterns detected.