Back to skill

Security audit

LinkedIn 人员工作经历查询,按人员 ID 从 LinkedIn数据获取含公司名称、职位与起止日期的就业经历。帮助招聘人员、用人经理与销售团队核验职业履历、评估专业经验、筛选候选人——适合候选人筛选、背景调查与人才获取。

Security checks for vulnerabilities and agentic risk

Overview

This skill performs the advertised LinkedIn work-history lookup, but it also stores API keys locally and includes billing, payment-order, error-reporting, and silent version-check behavior that users should review first.

Install only if you are comfortable using the Upkuajing paid API, storing its API key in a local plaintext .env file, and allowing the skill to access account and recharge-order endpoints. Confirm paid queries carefully, verify any payment URL before opening it, and avoid including sensitive personal data, tokens, or full responses in error reports.

Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares only a simple LinkedIn work-history lookup purpose, but the instructions clearly indicate capabilities to read environment files, write API keys to disk, and make networked API calls without an explicit permission model. This increases the risk of overprivileged behavior and makes it harder for users or the platform to understand what data and local resources the skill can access.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior extends well beyond retrieving employment history: it includes API-key issuance, credential storage, account and balance queries, payment-order creation, pricing retrieval, error reporting, and version-check caching. This mismatch is dangerous because users invoking a data lookup skill may not expect account, payment, and local credential operations, which broadens the attack surface and can enable unintended data disclosure or financial actions.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
A skill presented as a LinkedIn experience query tool also instructs the agent to apply for API keys, inspect local credential files, query account information, and handle recharge workflows. Even if operationally useful, these functions exceed the user-expected scope and create opportunities for unnecessary credential exposure and account manipulation.

Description-Behavior Mismatch

Low
Confidence
84% confidence
Finding
The exception-reporting feature is outside the narrow purpose of querying employment history and may transmit request metadata and contextual details to the platform. While likely intended for support, it still expands data flows beyond the core function and can leak user or query context if not carefully minimized.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill can create recharge orders and direct the user to a payment URL, which introduces a financial operation unrelated to employment-history retrieval. Financial workflows are sensitive because they can cause monetary loss, be abused for phishing-like redirection, or normalize trust in off-platform payment actions.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The ability to request a new API key and automatically save it to a local .env file is not part of the direct business function of querying work history. Credential provisioning and storage are sensitive operations that can expose secrets, create unauthorized accounts, or persist credentials in insecure locations.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The file implements account authentication, API key issuance, balance checks, and recharge workflows for a third-party platform rather than LinkedIn experience retrieval as advertised. This capability mismatch is dangerous because it can mislead users into granting trust to code that performs unrelated account-management operations, increasing the risk of unauthorized billing, credential handling, or hidden platform coupling.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Creating recharge orders is unrelated to the declared purpose of analyzing a person's LinkedIn work history. In a skill context, hidden payment-enablement functionality expands the attack surface and may expose users to unexpected charges or financial workflow abuse if invoked by mistake or through deceptive packaging.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
Exposing account balance and pricing information is not necessary for a LinkedIn resume-analysis skill and indicates the skill has broader commercial platform access than advertised. While not directly exploitative by itself, this mismatch can leak sensitive business/account metadata and signals overprivileged integration.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The module performs an outbound HTTP POST to a remote version-check endpoint that is unrelated to the skill’s stated LinkedIn experience retrieval purpose. Even though only the skill name is sent, this creates undisclosed network-side telemetry and expands the trust boundary, which is risky in environments that expect skills to avoid unrelated external communications.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation explicitly allows sending request parameters, response data, and detailed error context to an error-report API. Although it says sensitive fields are 'automatically desensitized,' it provides no explicit warning to operators not to include personal data, tokens, or third-party confidential content, and auto-redaction is rarely complete for arbitrary nested payloads or free-form stack traces. In this skill context, LinkedIn employment-history lookups may involve personal profile data and identifiers, so error reporting can become a secondary data exfiltration path.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The code sends request metadata and a free-form 'context' field to an external endpoint, and that context could contain stack traces, request contents, user identifiers, or other sensitive data. Without visible sanitization, redaction, consent, or disclosure, this creates a plausible data leakage path from runtime failures to a third-party platform.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code automatically sends the skill name to a remote API during version checks without any user-facing warning, consent, or obvious opt-out. This creates silent telemetry and may leak tool usage information to a server, which is especially problematic because the network activity is not necessary for the core LinkedIn-analysis function.

Credential Access

High
Category
Privilege Escalation
Content
### **未设置API密钥**
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;
Confidence
98% confidence
Finding
The skill explicitly instructs checking for and using a secret stored in ~/.upkuajing/.env, which is credential access to a local secret store. Accessing local credential files is dangerous because it can expose API keys to the skill flow, increase the chance of accidental disclosure, and normalize secret harvesting behavior in what appears to be a simple data-query skill.

Credential Access

High
Category
Privilege Escalation
Content
请先检查 `~/.upkuajing/.env` 文件是否有 UPKUAJING_API_KEY;
如果未设置 UPKUAJING_API_KEY API密钥,请提示并让用户选择:
1. 用户有,由用户提供(手动添加到 ~/.upkuajing/.env 文件)
2. 用户没有,你可使用接口进行申请(`auth.py --new_key`),申请到新密钥后,会自动保存到 ~/.upkuajing/.env
等待用户选择;

### **账户充值**
Confidence
98% confidence
Finding
The instructions to obtain a new API key and automatically save it into ~/.upkuajing/.env combine credential creation with local secret persistence. This is risky because it creates and stores sensitive credentials outside a dedicated secret-management boundary, where other tools or users on the host may access them.

Credential Access

High
Category
Privilege Escalation
Content
"envFilePath": str(env_file)
        }

    # 保存到 .env 文件
    try:
        with open(env_file, 'w', encoding='utf-8') as f:
            f.write(f"{API_KEY_ENV}={api_key}\n")
Confidence
81% confidence
Finding
The code writes a newly issued API key into a plaintext .env file without any visible permission hardening or secure secret-storage mechanism. In a shared or weakly secured environment, plaintext credential storage can allow other local users or processes to recover the key and abuse the associated account.

Credential Access

High
Category
Privilege Escalation
Content
except IOError as e:
        return {
            "success": False,
            "message": f"API密钥申请成功,但保存到 .env 文件失败:{str(e)}。\n请手动设置环境变量 {API_KEY_ENV}。",
            "envFilePath": str(env_file)
        }
Confidence
78% confidence
Finding
Returning the environment file path in error output can disclose the credential storage location, which helps an attacker identify where secrets are kept. This is lower severity than direct secret disclosure, but in combination with plaintext storage it increases the likelihood of credential compromise.

Unpinned Dependencies

Low
Category
Supply Chain
Content
httpx>=0.23.0
Confidence
96% confidence
Finding
The dependency is specified with a lower bound only (`httpx>=0.23.0`), which allows installation of any future release, including versions with breaking changes or newly introduced security issues. This weakens build reproducibility and can expose the skill to supply-chain risk if an unsafe or incompatible version is later resolved.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/common.py:196