Back to skill

Security audit

Salesforce API Integration

Security checks for vulnerabilities and agentic risk

Overview

This Salesforce helper is transparent about its purpose, but it should be reviewed carefully because it can use powerful Salesforce credentials and persist business context locally without asking each time.

Install only if you are comfortable granting the skill Salesforce API authority and access to its declared local note folders. Use a least-privileged integration user, verify SF_INSTANCE_URL and SF_LOGIN_HOST are trusted Salesforce hosts, keep tokens and private keys out of Clawic data files, and review or disable automatic local memory writes if shared contacts, project notes, or subscription costs should not persist across sessions.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
records.md:13
Finding

Credential and Salesforce Data Disclosure Through Unvalidated Destination Variables

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:22
Finding

Excessive Default Access to Shared Contact, Project, Profile, and Financial Data Stores

Content
View full analysis
Remediation
View remediation
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 (26)

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

md
| Signature | Most likely cause | First move |
|---|---|---|
| 401 `INVALID_SESSION_ID` | Access token expired, or a sandbox token sent to production | Refresh; if refresh also fails, the login host is wrong (`test.salesforce.com` for sandboxes) |
| 400 `invalid_grant` at the token endpoint | JWT `aud`, `sub` or clock; or the user is not pre-authorized on the Connected App | Check `aud` matches the environment and that the user's profile is on the app (`auth.md`) |
| 400 `INVALID_FIELD` on a field you can see in the UI | Field-level security on the integration user, or the label instead of the API name | Rule 7 — check FLS first, then `describe` for the real API name |
| 400 `MALFORMED_QUERY` | Syntax, or a relationship name used where a field name belongs | `Account.Name` traverses, `AccountId` is the field; child subqueries use the plural relationship name |

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

md
| api_version | text (`vNN.0`) | none | Version segment in every URL and example; while unset, name the assumed version before acting (Rule 2) |
| default_org | text (org alias) | none | Which org in `## Org Context` / `orgs.md` an unqualified request means; unset means ask nothing and say which org the answer assumes |
| auth_flow | jwt-bearer \| web-server \| refresh-token \| client-credentials \| device | jwt-bearer | Which flow `auth.md` walks and what the examples pass to the token endpoint |
| code_style | curl \| python \| node \| sf-cli | curl | Language of every emitted example |
| bulk_threshold | number (records) | 5000 | Switch point from sObject Collections to Bulk 2.0 in Rule 3 |
| all_or_none | bool | true | Default for Collections and Composite: whole-batch rollback vs per-record results |
| sandbox_first | bool | true | Whether bulk writes, deletes and metadata deploys are rehearsed in a sandbox before production (Rule 8) |

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

md
| Treating a 403 as "no permission" | `REQUEST_LIMIT_EXCEEDED` is also a 403, and the fix is the opposite of granting access | Branch on `errorCode`, never on the HTTP status alone |
| Retrying a failed insert without an idempotency key | Salesforce processed the first one; the timeout was the response, not the write | Upsert on external id, or query for the record before retrying (Rule 4) |
| Mass owner changes during business hours | Sharing recalculation cascades and can lock the org for everyone | Defer sharing calculation, run off hours, and stage in a sandbox first (`migration.md`) |
| Storing an access token or a JWT private key in the notes file | It leaks with the first backup or screen share | Pointer only: `keychain:sf-prod`, `file:~/.certs/sf-jwt.key` |
| Testing a load against 10 records | Governor limits and lock contention only appear at chunk boundaries — 10 records never crosses one | Rehearse with at least 1,000 records, spanning more than one 200-record chunk (Rule 5) |

## Where Experts Disagree

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

md
| A migration or integration the user tracks as a piece of work | `~/Clawic/data/projects/<project>.md` (**shared**) | One file per project |
| Salesforce edition, license count and what it costs | `~/Clawic/data/finances/subscriptions.md` (**shared**) | One row, amount with currency inside the value |
| **Anything durable this table does not name** | `~/Clawic/data/salesforce-api-integration/<plural-noun>.md`, or `artifacts/<kebab-name>.md` if it is a long text read whole | Name the file after what it holds, never after when it was made; add its `## Boxes` line in the same turn |
| Access tokens, client secrets, private keys, passwords, security tokens | Nowhere under `~/Clawic/data/` | Pointer only — see Secrets |

Deciding where something new goes, in order: **would another skill want to read it?** → shared box. **Is it a text read whole when its subject comes up** (design, mapping, runbook, policy)? → `artifacts/`. **Is it one more row of something that accumulates?** → a section of `memory.md` until the threshold, then its own box.

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 · memory-template.md (reported line 23)May include surrounding context.

md
| A migration or integration the user tracks as a piece of work | `~/Clawic/data/projects/<project>.md` (**shared**) | One file per project |
| Salesforce edition, license count and what it costs | `~/Clawic/data/finances/subscriptions.md` (**shared**) | One row, amount with currency inside the value |
| **Anything durable this table does not name** | `~/Clawic/data/salesforce-api-integration/<plural-noun>.md`, or `artifacts/<kebab-name>.md` if it is a long text read whole | Name the file after what it holds, never after when it was made; add its `## Boxes` line in the same turn |
| Access tokens, client secrets, private keys, passwords, security tokens | Nowhere under `~/Clawic/data/` | Pointer only — see Secrets |

Deciding where something new goes, in order: **would another skill want to read it?** → shared box. **Is it a text read whole when its subject comes up** (design, mapping, runbook, policy)? → `artifacts/`. **Is it one more row of something that accumulates?** → a section of `memory.md` until the threshold, then its own box.

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

md
| The exact number the sales meeting quotes | The report | It carries the org's own filters, groupings and currency conversion. A SOQL rebuild that differs by 2% is worse than useless |
| Rows to process, load or export | SOQL or Bulk (`soql.md`, `bulk.md`) | No row ceiling, no factMap to unpick |
| More than a couple of thousand rows | Bulk query | The synchronous report path truncates |
| A recurring extract | SOQL, written once | Reports get edited by whoever owns them, without warning |

The trap in both directions: rebuilding a trusted report in SOQL and quietly getting a different number, or scraping a report for bulk data it was never meant to deliver.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill metadata requires SF_INSTANCE_URL from the environment while the body also states the instance URL must come from the OAuth token response. This inconsistency can cause the agent to send authenticated Salesforce requests to the wrong host, risking misrouting, failed requests, or accidental disclosure of API traffic to an unintended Salesforce domain if stale or incorrect environment values are used.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill says memory-template.md is the only file opened for writing, but later instructs writes to shared contacts, projects, and finances files. Contradictory persistence rules create ambiguity about where data may be stored, which can lead an agent to write sensitive CRM-related information into broader shared note locations without consistent safeguards or user awareness.

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

A class annotated as a REST resource is served at "$SF_INSTANCE_URL/services/apexrest/<urlMapping>" — a different base path from /services/data/, and it carries no API version segment.

bash
curl -X POST "$SF_INSTANCE_URL/services/apexrest/orders/v1" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"customerKey":"EXT-4471","lines":[{"sku":"A-1","qty":2}]}'

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

The assertion's claims: iss = Consumer Key, sub = the integration user's username (the sandbox username in a sandbox), aud as above, exp a few minutes out — Salesforce rejects a long-lived assertion, so mint a fresh one per token request rather than caching the JWT.

bash
curl -X POST "https://login.salesforce.com/services/oauth2/token" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
  -d "assertion=$SIGNED_JWT"

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

md
| 401 `INVALID_SESSION_ID` on a token minted seconds ago | Token sent to the wrong instance URL | Use the `instance_url` from that token response |
| Everything fails after a deactivation | The integration user was disabled | Reactivate or repoint; no token can outlive its user |

**Before finishing an auth session**: write the org's alias, type, instance URL, API version, flow and credential *pointer* into `## Org Context` — or `orgs.md` from the second org — and put any certificate or secret expiry into the `## Due` table of `memory.md`. Never write the token, the secret, the key or an `sfdx` auth URL; the pointer is `keychain:sf-prod`, `env:SF_CLIENT_SECRET`, `file:~/.certs/sf-jwt.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 · bulk.md (reported line 39)May include surrounding context.

bash
# 1. Create the job
curl -X POST "$SF_INSTANCE_URL/services/data/v62.0/jobs/ingest" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"operation":"upsert","object":"Account","externalIdFieldName":"ERP_Id__c",
       "contentType":"CSV","lineEnding":"LF"}'

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation instructs the agent to append to and potentially create local files under ~/Clawic/data/salesforce-api-integration/loads/<year>.md and related artifacts. That expands the skill's behavior beyond Salesforce API actions into persistent filesystem writes, which can occur without explicit per-run user consent and can leak sensitive operational metadata such as object names, row counts, job IDs, mappings, and failure causes onto the local machine.

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

Up to 200 records, one operation, one call. Mixed object types are allowed in the same payload via attributes.type.

bash
curl -X POST "$SF_INSTANCE_URL/services/data/v62.0/composite/sobjects" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"allOrNone": false,
       "records":[

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file demonstrates a deletion call (DELETE ...?ids=...) but does not include any warning about data loss, confirmation, or the irreversible nature of the operation. Under the markdown-specific SQP-2 criteria, user-facing documentation should warn when described behavior can affect user data or system integrity.

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

Upload

bash
curl -X POST "$SF_INSTANCE_URL/services/data/v62.0/sobjects/ContentVersion" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"Title":"Signed contract","PathOnClient":"contract.pdf","VersionData":"<base64>"}'

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instruction 'Read this file only when WRITING' does not define what counts as 'WRITING' or provide any exclusion conditions. In a markdown skill file, this broad trigger can overlap with many ordinary agent actions and may cause unintended invocation because there is no explicit scope or negative examples.

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 · memory-template.md (reported line 49)May include surrounding context.

md
Everything except artifacts, per-object schema files, load records and the shared boxes begins inside `memory.md`. Splitting is a procedure, not a suggestion:

1. **Who and when**: the agent about to append counts the section's entries **before** adding the one that would cross the line.
2. **Threshold**: past **~15 entries or ~40 lines of real content** — scaffolding, headings and comments do not count, and in tables the entry count rules — then, in the same turn: create the new file in `~/Clawic/data/salesforce-api-integration/`, move the whole section into it, **delete the section from `memory.md`**, add its line to `## Boxes`, and append the new entry to the new file.
3. **Identical headings on both sides** of the move, so the split is a copy-paste and never a rewrite.
4. **Precedence**: never leave a copy behind. If the same data ever appears in both places, the extracted file wins and the `memory.md` copy is deleted.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
84% confidence
Finding

The default bypass_validation_rules: ask-first normalizes a potentially dangerous operational mode in which business-rule enforcement may be disabled. In a Salesforce integration context, validation rules often protect data integrity and policy compliance; making bypass an expected option increases the chance of unsafe writes, especially under time pressure or vague user approval.

Content

Scanner excerpt · memory-template.md (reported line 95)May include surrounding context.

csv_date_format: "YYYY-MM-DDThh:mm:ssZ" safety_posture: hard_delete: forbidden bypass_validation_rules: ask-first sync_posture: poll_minutes: 15

text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The section explicitly discusses irreversible and destructive recovery actions such as hard delete and restarting from an empty org, but it does not begin with a prominent safety warning or operator confirmation guidance before presenting those options. In a migration skill, this can normalize risky actions and increase the chance that a user performs irreversible deletion without adequate backup, approval, or validation.

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

bash
# Whole record, every field the user can see
curl "$SF_INSTANCE_URL/services/data/v62.0/sobjects/Account/001xx000003DGbYAAW" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN"

# Named fields only — smaller, faster, and it fails loudly on a field you cannot read

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

POST the report id with a modified reportMetadata to filter without touching the saved report:

bash
curl -X POST "$SF_INSTANCE_URL/services/data/v62.0/analytics/reports/00Oxx0000012345?includeDetails=true" \
  -H "Authorization: Bearer $SF_ACCESS_TOKEN" -H "Content-Type: application/json" \
  -d '{"reportMetadata":{"reportFilters":[
        {"column":"OPPORTUNITY.STAGE_NAME","operator":"equals","value":"Proposal"}],

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill tells the agent to create or modify local tracking files but does not pair that instruction with an explicit warning that it will write to the filesystem. This weakens user awareness and consent, increasing the chance of unexpected local state changes or retention of potentially sensitive migration and failure data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file includes a concrete download command that saves remote content directly to contract.pdf via --output, which is a file-write operation. While the section explains the API behavior, it does not explicitly warn the user that running the command will create or overwrite a local file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The line 'Runs everything from Python' imposes a specific implementation language in the template content without offering the user a choice or documenting an opt-in. This can violate language or locale policy where skills should not force a language absent explicit user preference or justified scope.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
memory-template.md:61