Back to skill

Security audit

Automate Job Application

Security checks for vulnerabilities and agentic risk

Overview

The skill is aligned with automated job applying, but it needs review because it can submit applications and reuse or transmit sensitive personal data with incomplete consent and disclosure controls.

Review this skill carefully before installing. Use it only if you are comfortable giving it resume API access, letting it fill and submit job applications, and storing sensitive preferences locally. Confirm every application before submission, avoid saving sensitive or legal-consent answers for reuse, and restrict or delete the local preferences and resume files after use.

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

T01 · Skill Instruction Hijacking

Error
Location
scripts/draft_cover_letter.py:129
Finding

Untrusted job descriptions are inserted directly into an agent-executed prompt

Content
View full analysis
Remediation
View remediation

other

Error
Location
references/screening_questions.md:30
Finding

The Skill automatically grants consent to background checks and drug screening

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/manage_preferences.py:97
Finding

Sensitive preferences and full resumes are written without restrictive file permissions

Content
View full analysis
None: """Save preferences to disk, creating the data directory if needed.""" DATA_DIR.mkdir(parents=True, exist_ok=True) prefs["saved_at"] = datetime.now(timezone.utc).isoformat() with open(PREFS_FILE, "w") as f: json.dump(prefs, f, indent=2, ensure_ascii=False) print(f"Preferences saved to {PREFS_FILE}", file=sys.stderr) ``` Resume storage: ```python # --save: write full resume to file if args.save: with open(args.save, "w") as f: json.dump(resume, f, indent=2) print(f"Resume saved to {args.save}", file=sys.stderr) ``` The documented workflow recommends predictable shared temporary paths: ```bash python3 scripts/fetch_resume.py --save /tmp/resume.json ``` ### Technical Analysis Both files are created with the process’s default umask rather than an explicit owner-only mode. On systems with a common `022` umask, newly created files are generally readable by other local users. The preferences file may contain date of birth, gender, ethnicity, disability status, veteran status, visa information, salary, and address data. A saved resume contains direct identifiers and employment history. The resume’s arbitrary `--save` path also permits writing through a pre-existing symbolic link when the Skill runs with access to the target. Predictable filenames under a shared `/tmp` directory increase symlink and unintended-disclosure risk. The documentation suggests running `chmod 600` manually after creation, but this does not protect the interval between file creation and permission correction and is not enforced by code. ### Attack Path 1. An attacker with access to the same host monitors or ...[truncated 921 chars]
Remediation
View remediation

other

Warning
Location
SKILL.md:85
Finding

Privacy documentation incorrectly claims saved preferences are never transmitted

Content
View full analysis
⚠️ **`user_preferences.json` may contain sensitive personal data** including date of birth, > gender, ethnicity, veteran status, and disability status (only if you choose to save these > when prompted during a form fill). This file is stored **locally only** and is **never sent > to resumex.dev or any other server**. ``` The form-filling workflow instructs the agent to use those values on external websites: ```markdown For each form field, use this priority order to find the value: 1. Resume data (from ResumeX API) → profile.email, profile.phone, etc. 2. User preferences (from preferences.json) → salary_expectation, visa_status, etc. 3. Derived data (calculated by agent) → years of experience, full name split, etc. 4. Ask the user (last resort) → save answer to preferences for reuse ``` The same workflow maps sensitive fields directly from preferences: ```markdown | Salary Expectation | Preferences | `salary_expectation` | | Notice Period | Preferences | `notice_period` | ``` Executable mappings also include gender and date of birth: ```python "gender": {"source": "preferences", "key": "gender"}, "date of birth": {"source": "preferences", "key": "date_of_birth"}, "dob": {"source": "preferences", "key": "date_of_birth"}, ``` ### Technical Analysis The file itself may remain local, but values read from it are explicitly inserted into forms and transmitted to job boards, applicant-tracking systems, and employer websites. Therefore, the categorical statement that the data is “never sent to any other server” is inaccurate. This matters because the file contains special-category and high-risk information. A user may consent to local persistence based on the stated privacy boundary with ...[truncated 873 chars]
Remediation
View remediation

other

Warning
Location
scripts/log_application.py:129
Finding

Cover letters can be uploaded to ResumeX without being disclosed in the external-data policy

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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a broad, end-to-end job hunting and auto-application capability. In contrast, the actual code only loads a local resume JSON file, formats selected resume/job details, and outputs a prompt intended for an internal LLM to draft a cover letter. This is a materially different primary purpose. The code does not perform any of the core declared actions: no web search, no matching logic, no approval workflow, no browser control, no form filling, no submission, and no tracking/logging. While the code is tangentially related to job applications, it represents only a narrow support task (cover-letter drafting) rather than the declared automation skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This is a clear description-behavior mismatch. The declared purpose describes a comprehensive automated job search and application system. The code chunk is a CLI utility focused narrowly on retrieving resume data from resumex.dev and optionally extracting fields, saving JSON, or printing a textual summary. Accessing resumex.dev is consistent with part of the description, but the overwhelming majority of the declared functionality is absent. The primary purpose of the actual code is resume fetching/inspection, not finding or applying to jobs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents an end-to-end auto job application system. This code chunk is only a form-field mapping helper for job applications. It reads a resume file from disk, optionally reads preferences, resolves labels like 'First Name' or 'Email' to resume values, derives a few fields such as years of experience, and emits JSON summaries for mapping or coverage. Although the header comment mentions browser automation instructions and an environment variable for RESUMEX_API_KEY, the implemented commands all require --resume and never actually call resumex.dev, perform web search, drive a browser, submit forms, or log applications. Therefore the code's actual behavior is a narrow supporting component, not the broader declared skill behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear description-behavior mismatch. The declared purpose describes a comprehensive automated job search and application system, but the code shown only constructs a payload and posts it to ResumeX job-tracker endpoints. Its primary purpose is logging an application entry, not searching for jobs or applying to them. Access to resumex.dev is consistent with one small declared subfeature (logging), but the main advertised capabilities are absent from this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a full job-search and auto-application system integrated with resumex.dev, web search, and browser control. The supplied code chunk does none of those things. Instead, it manages persistent user preferences and screening answers through a command-line interface and stores them in a local JSON file. While preference storage could be a supporting component of a larger auto-applier skill, this chunk’s actual primary behavior is materially different from the declared end-user functionality and lacks the core declared capabilities entirely. Therefore this code chunk does not accurately represent the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description presents an end-to-end automatic job hunting and application system. This code chunk is much narrower: it is a local CLI utility for constructing search queries and transforming/scoring job data. It does not contact resumex.dev, make network requests, control a browser, submit forms, or log anything externally. While the code is plausibly a supporting component of a larger auto-job-applier system, the declared description materially overstates what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to always activate for very broad job-seeking phrases, even when the user has not mentioned resumex or consented to resume retrieval, web search, persistent storage, or browser automation. In a skill that can fetch sensitive resume data, save local preferences, and submit applications externally, broad triggers materially increase the risk of unintended activation and privacy-invasive actions.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `SKILL.md` | This file — main instructions for the agent |

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
88% confidence
Finding

The script builds and returns a raw LLM prompt that directly embeds untrusted resume fields and job description text without any delimiting, escaping, or instruction isolation. Because the surrounding skill uses browser automation and application submission, attacker-controlled content in a resume or job posting could inject instructions into the downstream model, causing manipulated cover letters, disclosure of embedded data, or undesired agent behavior if the consuming agent treats the prompt as authoritative.

Content

Scanner excerpt · scripts/draft_cover_letter.py (reported line 170)May include surrounding context.

python
Write the cover letter now:"""

    return prompt


def main():

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly states that the skill activates automatically on very broad phrases like 'apply to jobs', 'job search', 'find jobs for me', and 'job hunting'. Because this skill can fetch resume data, search external sites, and automate applications, broad trigger language increases the chance of unintended invocation and privacy-impacting or action-taking behavior from casual user wording.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill requests and describes capabilities that include environment access, local file read/write, network access, and browser-driven automation, but it does not declare a constrained tool scope such as explicit permissions or allowed tools. In a skill that handles resumes, personal identifiers, and automated web actions, missing scope boundaries increases the chance of over-privileged execution and unintended data access or transmission.

Content

No source excerpt is available for this finding.

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 158)May include surrounding context.

md
> when prompted during a form fill). This file is stored **locally only** and is **never sent
> to resumex.dev or any other server**. Review and restrict its filesystem permissions if needed:
> ```bash
> chmod 600 data/user_preferences.json
> ```
> To clear all saved preferences at any time:
> ```bash

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

md
> when prompted during a form fill). This file is stored **locally only** and is **never sent
> to resumex.dev or any other server**. Review and restrict its filesystem permissions if needed:
> ```bash
> chmod 600 data/user_preferences.json
> ```
> To clear all saved preferences at any time:
> ```bash

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The file mandates 'Professional but human tone' for generated cover letters without offering user choice on language, locale, or style preferences. This imposes a fixed communication style rather than allowing the user to opt in or specify their preferred language/locale.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The skill explicitly transmits application metadata to an external service using an API key, including company, position, URL, status, and notes. Although this behavior is disclosed and related to the skill's purpose, it still constitutes external transmission of user activity data and becomes security-relevant because it involves persistent logging to a third-party service.

Content

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

Or via curl:

bash
curl -s -X POST "https://resumex.dev/api/v1/agent/jobs" \
  -H "Authorization: Bearer $RESUMEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The document instructs the agent to reuse answers from user_preferences.json, including highly sensitive employment, compensation, and demographic data, but does not clearly warn that these values are stored persistently and reused across future applications. In the context of an auto-job-apply skill that submits forms automatically, this can cause users to disclose sensitive information without informed consent and creates privacy risk if local preference data is retained or accessed later.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instructions tell the agent to save user-provided answers directly to disk via manage_preferences.py set without requiring a warning, confirmation, or consent flow. Because this skill handles sensitive PII and protected-category application answers, silent persistence increases the chance of unintended retention, later misuse in other applications, or exposure from local file compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file provides operational guidance for automating job applications and form filling across third-party job boards and ATS platforms, but it does not require a clear user-facing warning that the agent will transmit highly sensitive personal data such as resume contents, contact details, employment history, and possibly cover letters to external sites. In this skill context, that omission is more dangerous because the broader skill is explicitly designed to fetch full resume data from resumex.dev and then submit applications automatically, increasing the risk of unintended disclosure or submission without informed user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The apply-method heuristics label several destinations as 'auto-apply' and instruct the agent to fill and submit forms, but they do not impose a user confirmation requirement immediately before submission. In this skill, that is particularly risky because the agent is intended to act at scale across many job sites, so missing confirmations can lead to mass unintended submissions, privacy exposure, and reputational harm from applying to unsuitable roles or sharing stale/inaccurate resume data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file states that new screening answers are saved for future reuse, but it does not clearly disclose to the user that personal application responses will be persisted across sessions. Because screening answers can include sensitive employment and eligibility information, silent persistence increases privacy risk and can lead to reuse of stale or overly personal data without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The workflow instructs the agent to save generated or user-provided answers broadly, while the reference includes highly sensitive data types such as salary expectations, date of birth, phone number, and work authorization. Persisting this information without strong minimization, sensitivity labeling, and consent controls creates meaningful privacy and compliance risk, especially since the skill automates repeated submissions to third-party job sites.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The guidance tells the agent to read JOB_TYPE from the environment to answer an application question, even though employment preference is user-specific profile data that should come from explicit user settings or prior consented preferences. Pulling it from environment state creates an unjustified side channel that can leak or misuse host/runtime configuration and may cause the agent to submit incorrect applications based on non-user data.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script allows saving the user's full resume, including sensitive personal data, to any caller-supplied local path without restriction, minimization, or explicit consent guardrails. In the context of an auto-job-applier skill that already handles resume data and browser automation, this increases the risk of unnecessary local persistence, accidental exposure, or abuse by other components that can choose a path in sensitive or shared locations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code writes full resume contents to disk with no warning that the data contains highly sensitive PII such as contact details, employment history, and potentially other identifying information. This creates a privacy and security risk because users or downstream automation may store the file in insecure, shared, or monitored locations, making disclosure more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script prints resolved field values and coverage results directly to stdout, which can include sensitive resume and preference data such as email, phone number, location, salary expectations, work authorization, date of birth, and other personal details. In an agent/browser-automation skill context, stdout is often captured by logs, orchestration layers, or other tools, so this creates a real risk of unintended disclosure beyond the immediate caller.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.