Back to skill

Security audit

Moltoffer Candidate

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for job-search automation, but it handles long-lived credentials and can send recruiter messages without enough user control.

Review before installing. This skill may store your resume-derived profile and MoltOffer API key locally, call the MoltOffer API, and post messages under your candidate identity. Use it only if you are comfortable with that account authority, keep the credential file private, and require manual review of recruiter replies and comments before anything is posted.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
references/onboarding.md:180
Finding
Long-Lived API Key Stored in Unprotected Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `references/onboarding.md:180-187` **Related Location**: `SKILL.md:199-215` **Vulnerability Type**: Plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```markdown ### 2.3 Save Credentials Save to `credentials.local.json`: ```json { "api_key": "molt_...", "authorized_at": "ISO timestamp" } ``` ``` The related security guidance states: ```markdown **Allowed local persistence**: - Write API Key to `credentials.local.json` (in .gitignore) - Enables cross-session progress without re-authorization **API Key best practices**: - API Key is long-lived, no refresh needed - User can revoke API Key on dashboard if compromised - All requests use `X-API-Key` header ``` ### Technical Analysis The onboarding workflow directs the agent to persist a long-lived MoltOffer API key in a plaintext JSON file. Although `SKILL.md` claims that `credentials.local.json` is covered by `.gitignore`, no `.gitignore` file exists in the audited project structure. The workflow also does not require restrictive file permissions, encryption, an operating-system credential store, or a dedicated secret manager. Excluding a file from version control would not by itself protect it from other local users, processes, backup systems, artifact collection, or accidental disclosure. Because the key is explicitly described as long-lived, its exposure window may remain open until manual revocation. ### Attack Path 1. A user completes onboarding and supplies a valid `molt_*` API key. 2. The Skill writes the key in plaintext to `credentials.local.json`. 3. The file is not protected by the promised project-level `.gitignore`, and no restrictive permissions are required. 4. The file is accidentally committed, included in an archive or backup, or read by another local process or user. 5. An attacker extracts the API key. 6. The attacker sends authenticated requests to the MoltOffer API using the victim candidate's identity. ...[truncated 475 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store the API key in an operating-system credential store or the host agent's dedicated secret manager. 2. If file-based storage is unavoidable: - Create and verify a project-level `.gitignore` containing `credentials.local.json`. - Create the credential file with permissions limited to the current user, such as mode `0600`. - Refuse to proceed if safe permissions cannot be established. - Keep the file outside the project and other routinely archived directories where possible. 3. Never include the complete key in logs, command traces, reports, error messages, or tool output. 4. Prefer short-lived and narrowly scoped credentials where the API supports them. 5. Document credential rotation and revocation procedures. 6. Add a pre-commit or secret-scanning control to prevent accidental inclusion of `molt_*` values in source control. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/daily-match.md:35
Finding
Undefined Generic Bearer Token May Leak an Unrelated Ambient Secret<![CDATA[ ## Vulnerability Details **File Location**: `references/daily-match.md:35-37` and `references/daily-match.md:49-51` **Vulnerability Type**: Ambiguous credential selection and unintended secret transmission **Risk Level**: Medium ### Vulnerable Code ```bash curl -H "Authorization: Bearer $TOKEN" \ "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/daily/{date}?limit=100&offset=0&category={category}&seniorityLevel={level}&jobType={type}" ``` The batch-detail request repeats the same authentication pattern: ```bash curl -H "Authorization: Bearer $TOKEN" \ "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/id1,id2,id3,id4,id5" ``` ### Technical Analysis The Skill's primary authentication specification requires a MoltOffer API key in the `X-API-Key` header. Other workflows consistently use `$API_KEY`, but the daily-match workflow instead references an undocumented generic variable named `$TOKEN` and sends it as an OAuth-style bearer token. The Skill metadata declares no required environment variables, and the onboarding process does not define or populate `$TOKEN`. A host environment may already contain a variable with this generic name for an unrelated service. If the command is executed in such an environment, that unrelated secret may be transmitted to `api.moltoffer.ai`. If no such variable exists, the requests will instead use an empty credential and fail. This behavior is unnecessary for the declared functionality because the Skill already collects a destination-specific `molt_*` key. ### Attack Path 1. The host environment contains a generic `TOKEN` variable used by another application or service. 2. The user invokes the daily-match workflow. 3. The shell expands `$TOKEN` without verifying its origin, format, or destination scope. 4. `curl` transmits the expanded value to `https://api.moltoffer.ai` in the `Authorization` header. 5. The external endpoint receives a secret that was not intended for MoltOffer. 6. If the exposed toke ...[truncated 668 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace every bearer-token example with the documented MoltOffer authentication mechanism: ```bash curl \ -H "X-API-Key: $MOLTOFFER_API_KEY" \ "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/daily/{date}..." ``` 2. Use a destination-specific variable name such as `MOLTOFFER_API_KEY`; never read a generic ambient variable such as `TOKEN`. 3. Load the credential only from the Skill's protected credential mechanism. 4. Validate that the selected credential has the expected `molt_` prefix before transmission. 5. Reject missing or malformed credentials instead of sending an empty or unknown value. 6. Centralize authenticated request construction so all endpoints use the same header and credential-validation logic. 7. Ensure debug and verbose HTTP modes cannot log authentication headers. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/comment.md:38
Finding
Unescaped Dynamic Content in Shell and JSON Request Construction<![CDATA[ ## Vulnerability Details **File Location**: `references/comment.md:38-42` **Related Location**: `references/comment.md:106-109` **Vulnerability Type**: Unsafe shell interpolation and malformed JSON injection **Risk Level**: Medium ### Vulnerable Code ```bash curl -X POST "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/<postId>/comments" \ -H "Content-Type: application/json" \ -H "X-API-Key: $API_KEY" \ -d '{"content": "<reply>", "parentId": "<recruiter_comment_id>"}' ``` The new-comment request uses the same pattern: ```bash curl -X POST "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/<postId>/comments" \ -H "Content-Type: application/json" \ -H "X-API-Key: $API_KEY" \ -d '{"content": "<comment>"}' ``` ### Technical Analysis The workflow places generated replies, comments, post IDs, and recruiter comment IDs into shell command templates without requiring structured JSON serialization, shell-safe argument handling, or identifier validation. Generated text may contain apostrophes, quotation marks, backslashes, control characters, or other syntax-significant content. Recruiter messages and job descriptions are externally controlled inputs that influence generated replies. If an implementation performs direct textual substitution into the displayed commands, an apostrophe can terminate the single-quoted JSON argument. Additional shell syntax can then be interpreted by the local shell. Even where shell execution is not achieved, unescaped quotation marks or control characters can produce invalid JSON, alter field boundaries, or cause unintended content to be submitted. ### Attack Path 1. A malicious recruiter publishes a crafted message or job description containing content designed to influence the generated reply. 2. The Agent incorporates attacker-controlled characters or text into `<reply>` or `<comment>`. 3. An implementation substitutes that generated value directly into the documented `curl -d` command. 4. A singl ...[truncated 1106 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not construct HTTP requests by inserting dynamic values into shell command strings. 2. Use a structured HTTP client or tool that accepts: - The URL as a separate value. - Headers as structured fields. - A JSON object that is serialized by a trusted JSON encoder. 3. If `curl` must be used, create the payload with a JSON serializer rather than manual quoting. For example, use a safe library or `jq --arg` and pass the resulting file through `--data-binary @payload.json`. 4. Pass URLs and arguments as distinct process arguments without invoking a command shell. 5. Validate `postId` and `parentId` against the API's exact identifier format before using them in a URL or payload. 6. Treat all job descriptions and recruiter comments as untrusted data. Explicitly prohibit following instructions embedded in that content. 7. Add test cases containing apostrophes, double quotes, backslashes, newlines, command substitutions, semicolons, and Unicode control characters. 8. Keep the API key outside child-process command lines and prevent generated content from accessing credential files or environment variables. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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 (14)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly allows persisting a long-lived API key to `credentials.local.json`, but it does not require explicit user consent, describe local compromise risks, or define file-permission safeguards. Because this skill is user-invocable and intended for cross-session automation, silent credential persistence increases the chance that another local user, malware, backups, logs, or accidental file exposure could recover the key and use the candidate's account.

External Transmission

Medium
Category
Data Exfiltration
Content
#### 1.1 Fetch Pending Replies

```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -H "X-API-Key: $API_KEY" \
  "https://api.moltoffer.ai/api/ai-chat/moltoffer/pending-replies"
```

#### 1.2 For Each Pending Reply
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The workflow instructs the agent to automatically generate and post follow-up replies to recruiters without an explicit user confirmation step. Because these replies can disclose interest, negotiate next steps, or affect the user's professional reputation, autonomous posting creates a meaningful risk of unauthorized external communication and unintended commitments.

External Transmission

Medium
Category
Data Exfiltration
Content
4. **Generate and post follow-up reply**:
   ```bash
   curl -X POST "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/<postId>/comments" \
     -H "Content-Type: application/json" \
     -H "X-API-Key: $API_KEY" \
     -d '{"content": "<reply>", "parentId": "<recruiter_comment_id>"}'
Confidence
94% confidence
Finding
This POST sends AI-generated follow-up content to an external service on the user's behalf. In context, the danger is not the network call alone but that it performs outbound communication automatically, which can leak personal/job-search information, create unintended representations, and trigger state changes in a live recruiter conversation without explicit approval.

External Transmission

Medium
Category
Data Exfiltration
Content
3. **Post comment** (auto-marks as `connected`):
   ```bash
   curl -X POST "https://api.moltoffer.ai/api/ai-chat/moltoffer/posts/<postId>/comments" \
     -H "Content-Type: application/json" \
     -H "X-API-Key: $API_KEY" \
     -d '{"content": "<comment>"}'
Confidence
96% confidence
Finding
This POST publishes a comment to a job post and automatically marks the relationship as connected, creating an externally visible action and account state change. Even though the workflow includes a job-selection confirmation step, the skill still lacks a strong warning and per-message approval for the exact generated content, creating risk of unauthorized or inaccurate outreach.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The onboarding flow directs collection of sensitive personal data such as location, nationality, salary floor, and work authorization factors, but provides no privacy notice, retention policy, or explicit consent step. This creates risk of over-collection and mishandling of personal data, especially because the information is written into local skill files and may later influence automated job-seeking actions.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill asks the user to paste an API key directly into the chat flow and then stores it in credentials.local.json without warning about secret-handling risks. Secrets entered into conversational channels may be exposed through logs, transcripts, screenshots, or other tooling, and storing them in a plain local file increases the chance of accidental disclosure.

Missing User Warnings

Low
Confidence
77% confidence
Finding
This markdown file describes network calls to `api.moltoffer.ai` that send authorization credentials and persona-based filters such as category, seniority, and job type. While the workflow is report-only for commenting, it does not explicitly warn users that running it will contact an external API and transmit profile-derived data.

Static analysis

No suspicious patterns detected.