T09 · Insecure Skill Coding Practices
- Location
scripts/bdjobs-login.js:42- Finding
BDJobs Credentials and Authentication Tokens Stored in Plaintext
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill matches BDJobs automation, but it stores and prints sensitive login data and can make live account changes without strong confirmation gates.
Review this carefully before installing. Use it only in a private environment where command output is not logged broadly, and do not enter BDJobs credentials unless you accept local plaintext storage and transmission to BDJobs-related APIs. Manually review each job, cancellation, and salary change before running live action scripts, and rotate or remove stored tokens/passwords after use.
scripts/bdjobs-login.js:42BDJobs Credentials and Authentication Tokens Stored in Plaintext
scripts/bdjobs-login.js:77Reusable Authentication Tokens Disclosed Through Standard Output
scripts/bdjobs-search.js:145Full Resume Duplicated into Search Results and Standard Output
There is a clear description-to-code mismatch. The declared purpose describes a full BDJobs automation skill with multiple user-facing capabilities, but the supplied code is only a stub that prints a console message and contains no functional implementation. This is a materially different actual behavior because the code does not perform the advertised actions at all.
The declared description describes a BDJobs automation skill with network/service-oriented job-search and application-management functionality. The supplied code chunk only initializes a local job profile artifact by writing provided resume text into data/resume.md. While resume setup could be loosely related to a job application workflow, this code does not implement the core declared capabilities and its primary purpose is materially different from the stated BDJobs automation behavior.
Referenced artifact was not completely inspected
3. Run `scripts/bdjobs-fetch-jobs.js` with `--keyword`, `--isFresher`, `--postedWithin`, `--pg`, and `--jobLocation` to fetch raw job lists from `GetJobSearch`
Referenced artifact was not completely inspected
3. Run `scripts/bdjobs-fetch-jobs.js` with `--keyword`, `--isFresher`, `--postedWithin`, `--pg`, and `--jobLocation` to fetch raw job lists from `GetJobSearch`
Referenced artifact was not completely inspected
3. Run `scripts/bdjobs-fetch-jobs.js` with `--keyword`, `--isFresher`, `--postedWithin`, `--pg`, and `--jobLocation` to fetch raw job lists from `GetJobSearch`
Printing the full logged-in data object exposes sensitive tokens directly to stdout, which is commonly captured by terminal logs, orchestrators, CI systems, telemetry, and debugging tools. Because these values appear to be active session credentials, disclosure can enable immediate account takeover or unauthorized job-application actions.
The skill directs collection and local storage of BDJobs usernames, passwords, resume content, and auth tokens in plaintext-like local files without any explicit consent, masking, encryption, retention limits, or access controls. If the skill directory, logs, backups, or downstream tools are exposed, an attacker could reuse credentials and session artifacts to take over the user's BDJobs account and harvest sensitive personal data.
The skill enables automated job applications, cancellations, and salary updates on a live user account without requiring an explicit confirmation checkpoint immediately before each account-changing action. In context, these are real external side effects that can affect a user's employment prospects, account state, and professional reputation if triggered mistakenly or through prompt manipulation.
The reference explicitly instructs the skill to use local files for profile and authentication data, including logged-in session material such as token, refreshToken, encryptId, and decodeId. Storing and handling these credentials without any warning, protection guidance, or minimization increases the chance of credential leakage, unauthorized account access, and session hijacking if the local environment or logs are exposed.
This script performs a real job application POST and persists the result based solely on a command-line jobId, with no in-script user confirmation, preview, or final consent gate before the irreversible action. In the context of an automation skill that can search and auto-apply to jobs, this creates a meaningful risk of unauthorized or unintended applications being submitted on behalf of the user, potentially harming the user's employment prospects and account reputation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
function buildSearchUrl({ keyword, isFresher, pg, jobLocation, postedWithin }) {
const u = new URL('https://api.bdjobs.com/Jobs/api/JobSearch/GetJobSearch');
const params = {
Icat: '', industry: '', category: '', org: '', jobNature: '', Fcat: '', location: jobLocation || '',
Qot: '', jobType: '', jobLevel: '', postedWithin: String(postedWithin || ''), deadline: '', keyword: keyword || '', pg: String(pg || 1),
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
function buildSearchUrl({ keyword, isFresher, pg, jobLocation, postedWithin }) {
const u = new URL('https://api.bdjobs.com/Jobs/api/JobSearch/GetJobSearch');
const params = {
Icat: '', industry: '', category: '', org: '', jobNature: '', Fcat: '', location: jobLocation || '',
Qot: '', jobType: '', jobLevel: '', postedWithin: String(postedWithin || ''), deadline: '', keyword: keyword || '', pg: String(pg || 1),
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
}
function buildSearchUrl({ keyword, isFresher, pg, jobLocation, postedWithin }) {
const u = new URL('https://api.bdjobs.com/Jobs/api/JobSearch/GetJobSearch');
const params = {
Icat: '', industry: '', category: '', org: '', jobNature: '', Fcat: '', location: jobLocation || '',
Qot: '', jobType: '', jobLevel: '', postedWithin: String(postedWithin || ''), deadline: '', keyword: keyword || '', pg: String(pg || 1),
This code reads credentials from a local JSON file and sends them over HTTPS to external BDJobs authentication endpoints. There is no confirmation prompt, warning message, or explanatory comment/docstring disclosing that sensitive credentials will be transmitted.
The script stores authentication artifacts including access token, refresh token, and account identifiers in a local JSON file and then includes them in console output. This creates multiple leakage paths: other local processes, logs, CI output, shell history collectors, or support artifacts could expose reusable credentials that allow account access or session hijacking.
The script writes bearer-style authentication material to disk in a predictable location under the working directory without any evident access controls or user disclosure. If the file is read by another local user, bundled into backups, committed accidentally, or collected by tooling, an attacker may reuse the token and refresh token to access or maintain access to the victim's BDJobs account.
The script sends a persistent user identifier (GUID) to a remote BDJobs-related endpoint without any in-file validation, minimization, or user-consent check at the point of use. In this skill’s context, that network call is core functionality, but it still exposes account-linked data flow and could leak or misuse personal activity information if the endpoint, configuration, or surrounding execution environment is compromised.
This code sends the user's GUID to a remote applied-jobs API and also fetches job data from external BDJobs endpoints, then emits records containing resumeText loaded from disk alongside job details. The file has no confirmation prompt, user-facing disclosure, or explanatory comments warning that personal data and profile-linked identifiers are being used in network-backed processing.
The request body includes userGuid, which is account-identifying data, and sends it to a remote HTTPS endpoint. This file has no confirmation prompt, explanatory comment/docstring, or user-facing disclosure before transmitting that data.
The script stores the full API response in data/lastSalaryUpdateResult.json without any filtering, retention control, or protection. If the response contains personal data, account metadata, or server-side tokens/details, that information becomes available to other local processes or users with filesystem access, increasing the risk of privacy leakage and unintended disclosure.
The file specifies "Dhaka/Bangladesh (GMT+6)" as the time zone, which imposes a specific locale in configuration without any indication that the user selected it or that the skill is region-specific. This can violate language/locale policy when a skill assumes a locale by default rather than offering choice or documenting the constraint.
The file states that data/appliedJobIds.json will be refreshed and later modified on success, but it does not warn users that local state files will be written or changed. For markdown descriptions, SQP-2 requires warnings when behavior can affect user data or system integrity.
The script reads account-related local files containing login and user details with no in-file access control checks, integrity validation, or disclosure of sensitive-data handling. In isolation this is expected for automation, but in an agent skill that processes credentials and account state, unguarded local reads increase the risk of privacy exposure or use of stale/tampered identity data.
On successful cancellation, the script modifies appliedJobIds.json by removing the job ID. Although this is part of local state tracking, the file write occurs without any confirmation, explanatory comment, or user-facing notice in the code.
The script writes lastUndoResult.json to the local data directory, which is a file-modifying operation. In this file there is no confirmation prompt, comment, or user-facing notice explaining that undo results will be persisted to disk.
Detected: suspicious.dangerous_exec, suspicious.exposed_secret_literal