T09 · Insecure Skill Coding Practices
- Location
scripts/add_candidate.py:10- Finding
Candidate Personal Information Is Stored in Plaintext Without Enforced Restrictive Permissions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This recruiting skill is locally scoped and not malicious, but it handles sensitive candidate data and gives interview/reject-style recommendations despite saying it never makes hiring decisions.
Review this skill carefully before installing. It appears local-only and does not show exfiltration or hidden execution, but it can store applicant personal information and evaluative ratings on disk and may produce recommendations that influence hiring decisions. Use only with clear human review, documented job-related criteria, appropriate privacy controls, and a retention/deletion process for candidate records.
scripts/add_candidate.py:10Candidate Personal Information Is Stored in Plaintext Without Enforced Restrictive Permissions
references/resume-screening.md:208Resume-Screening Workflow Produces Hiring Recommendations Contrary to Its Declared Safety Boundary
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.
## Disclaimer
This skill provides hiring process support only. All hiring decisions remain the responsibility of the hiring manager and organization. The skill does not guarantee candidate quality or success. Always comply with applicable employment laws and regulations.
The purpose and usage text explicitly says the system should identify who is worth interviewing and respond to prompts like 'Should we interview this person?', which directly delegates an employment-screening judgment to the skill. That is dangerous because it operationalizes automated candidate selection despite the broader metadata claiming the tool does not make hiring decisions.
The file gives concrete hiring recommendations such as interview/reject categories and next-step prioritization, which conflicts with the stated boundary that the skill should never make hiring decisions. In practice, users may treat these outputs as automated decision support, creating legal, compliance, and fairness risk and encouraging over-reliance on the model for employment decisions.
The skill explicitly describes local data storage under memory/recruiting/ and instructs use of scripts for data operations, which implies file read/write capabilities, yet it declares no tool scope or permissions. This creates a mismatch between documented behavior and declared access boundaries, increasing the chance the runtime grants broader filesystem access than intended or that users cannot accurately assess what the skill may touch.
The activation description is broad enough to trigger on many routine hiring-related mentions, including resume screening and offer-letter workflows that involve sensitive candidate data. Over-broad routing can cause the skill to activate in contexts where users did not intend local candidate storage or automated candidate evaluation, increasing privacy and compliance risk.
The trigger examples are broad enough to match common requests like 'help me describe this position,' which could cause the recruiting skill to activate in situations where the user did not explicitly intend to use hiring workflow functionality. While this is not a code-execution or data-exfiltration issue, over-broad activation can route unrelated conversations into a hiring context and increase the chance of inappropriate handling of user input.
The documentation models and operationalizes handling of candidate personal data including names, emails, notes, ratings, communication history, and interview pipeline state, but it does not include explicit privacy, retention, access control, or sensitivity guidance. In a recruiting context, this makes misuse, overcollection, unauthorized exposure, and noncompliant processing of employment-related personal data more likely.
The example output goes beyond neutral tracking and includes evaluative labels and decision-driving recommendations such as 'Strong hire,' 'Move to technical,' 'Reject John Smith or schedule technical,' and 'Complete debrief and decide.' In a hiring skill whose manifest claims it never makes hiring decisions or replaces human judgment, this creates a policy and safety mismatch that can steer employment decisions, increasing legal, compliance, and bias risks.
The 'When to Use' section lists generic phrases like 'Evaluate this candidate' and 'Should we interview this person?' without narrowing context, exclusions, or exact trigger scope. In a markdown skill description, these broad phrasings can cause unintended activation during normal discussion about recruiting.
The file defines storage and handling of candidate screening data, including identifiers, assessments, concerns, and recommendations, without any privacy, retention, access-control, or sensitive-data handling guidance. Candidate records are highly sensitive employment data, so missing safeguards increases the risk of improper collection, retention, bias documentation exposure, and regulatory noncompliance.
The caveat says the screening is assessment-only, but the surrounding content still produces explicit interview/reject outcomes and scheduling priority. This contradiction weakens the safeguard because users are likely to follow the concrete decision outputs rather than the disclaimer.
This script persists candidate personal data, including name and email, to a predictable local file under the user's home directory without any notice, consent prompt, retention control, or access protection. In a recruiting context this is sensitive personal information, so silent local persistence increases the risk of accidental exposure through shared machines, backups, or other local processes reading the file.
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.
#!/usr/bin/env python3
"""Create a new job posting."""
import json
import os
import uuid
This code performs a file write to the recruiting pipeline data store by opening pipeline.json in write mode and replacing its contents. Although the script prints a success message afterward, there is no pre-action warning, confirmation, or explanatory comment/docstring disclosing that it will modify persistent candidate data.
The manifest explicitly says the skill should never make hiring decisions, but this script accepts and persists evaluative candidate ratings such as 'strong', 'likely', 'maybe', and 'no_hire'. Storing recommendation-style ratings goes beyond neutral pipeline tracking and materially supports hiring decision-making behavior.
The invocation example "Show me the pipeline" is generic and could match common conversational requests outside this specific hiring workflow. The file does not provide limiting context or negative examples to clarify that it refers only to recruiting pipeline tracking.
No suspicious patterns detected.