Back to skill

Security audit

LinkedIn 人员搜索,按姓名、公司、职位与行业从 LinkedIn 数据找人。帮助招聘人员、销售团队与 B2B 线索构建者发掘 LinkedIn档案、寻源候选人、丰富联系数据——适合人才获取、猎头、候选人筛选与国际线索生成。

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to perform the advertised LinkedIn people search, but it handles API keys, paid account actions, version-check network calls, and retained personal search data in ways users should review before installing.

Install only if you trust the Upkuajing service and are comfortable with paid API use, local plaintext credential storage, and local retention of people-search results. Do not let the agent print `~/.upkuajing/.env`; configure the API key through a safer secret mechanism or ensure the file is owner-only. Review legal, privacy, and outreach obligations before using contactability or demographic fields, and delete stored task results when no longer needed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:36
Finding

Skill Instructions Expose the Complete Credential File

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 36-42
Vulnerability Type: Unnecessary credential disclosure
Risk Level: High

Vulnerable Code

markdown
API keys are required to use this Skill. API keys are stored in the `~/.upkuajing/.env` file:
```bash
cat ~/.upkuajing/.env

Example file content:

text
UPKUAJING_API_KEY=your_api_key_here
text

### Technical Analysis

The Skill instructs the Agent to print the entire contents of a credential file. The implementation only needs to determine whether `UPKUAJING_API_KEY` exists and then load its value internally. Displaying the file is not necessary for the declared LinkedIn person-search functionality and exceeds least-privilege requirements.

This behavior may place the API key—and any additional secrets stored in the same file—into terminal output, Agent context, conversation transcripts, debugging records, or other logs. Although the code sends the bearer token only to the fixed vendor API host, the documentation introduces a separate local disclosure channel.

### Attack Path

1. A user invokes the Skill without an API key already available in the process environment.
2. The Agent follows the documented credential-checking procedure.
3. The Agent executes `cat ~/.upkuajing/.env`.
4. The complete file contents are emitted to standard output.
5. The API key and any unrelated values in the file become accessible through the visible session, transcript, terminal capture, or logging infrastructure.
6. A party with access to that output can reuse the bearer token against the vendor API.

### Impact Assessment

Successful exposure may allow unauthorized use of paid API functions and access to account information associated with the bearer token. The scope is limited to credentials and other data present in `~/.upkuajing/.env`; no evidence indicates privilege escalation to operating-system administrator access.
Remediation
View remediation

Remediation Suggestions

  • Remove the instruction to print the entire .env file.

  • Check only whether the required variable exists and contains a nonempty value.

  • Never include the credential value in Agent-visible output.

  • Use a presence-only check such as:

    bash
    grep -q '^UPKUAJING_API_KEY=.' ~/.upkuajing/.env
    
  • Prefer the process environment or an operating-system credential store over a plaintext .env file.

  • If diagnostic output is necessary, return only a result such as API key configured: yes and never reveal a prefix or suffix of the key.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auth.py:62
Finding

API Key Is Written Without Restrictive Filesystem Permissions

Content
View full analysis

Vulnerability Details

File Location: scripts/auth.py, lines 62-74
Vulnerability Type: Insecure secret storage permissions
Risk Level: High

Vulnerable Code

python
# Ensure ~/.upkuajing directory exists
try:
    UPKUAJING_DIR.mkdir(parents=True, exist_ok=True)
except OSError as e:
    return {
        "success": False,
        "message": f"API key application succeeded, but directory creation failed: {str(e)}.",
        "envFilePath": str(env_file)
    }

# Save to .env file
try:
    with open(env_file, 'w', encoding='utf-8') as f:
        f.write(f"{API_KEY_ENV}={api_key}\n")

Technical Analysis

The directory and credential file are created without explicit permission modes. Their effective permissions therefore depend on the process umask. Under a common 022 umask, the directory may be created as 0755 and the file as 0644, which can make the bearer token readable by other local users.

Opening an existing path with open(..., 'w') also does not correct permissive permissions already assigned to that file. The implementation does not verify whether the destination is a symbolic link before overwriting it.

Attack Path

  1. An attacker has access to another account on the same host or to a local process running under a different identity.
  2. The victim runs python scripts/auth.py --new_key.
  3. The Skill creates ~/.upkuajing and writes the new bearer token to ~/.upkuajing/.env using umask-derived permissions.
  4. If those permissions permit access, the attacker reads the file.
  5. The attacker reuses the token to invoke authenticated vendor endpoints, consume paid services, or retrieve associated account information.

An additional local path-manipulation scenario is possible if an attacker can pre-create or replace the destination with a symbolic link before execution, subject to the permissions of the victim's home directory.

Impact Assessment

The ...[truncated 308 chars]

Remediation
View remediation

Remediation Suggestions

  • Create the credential directory with mode 0700.
  • Atomically create the credential file with mode 0600.
  • Correct permissions on existing paths before use.
  • Reject symbolic links and verify that the destination is a regular file owned by the current user.
  • Write to a securely created temporary file in the same directory and atomically replace the final file.
  • Avoid returning any portion of an existing key in diagnostic messages.

Example hardening approach:

python
UPKUAJING_DIR.mkdir(parents=True, exist_ok=True, mode=0o700)
os.chmod(UPKUAJING_DIR, 0o700)

flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
fd = os.open(env_file, flags, 0o600)
with os.fdopen(fd, "w", encoding="utf-8") as f:
    f.write(f"{API_KEY_ENV}={api_key}\n")

A production implementation should also handle existing files through a safe ownership, type, and permission validation path.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/common.py:434
Finding

Personal Search Results Are Persisted in Plaintext Without Access or Retention Controls

Content
View full analysis

Vulnerability Details

File Location: scripts/common.py, lines 434-450 and 475-482; invoked by scripts/linkedin_person_search.py, lines 129-131
Vulnerability Type: Insecure storage of personal data
Risk Level: Medium

Vulnerable Code

python
def ensure_task_dir(task_id: str) -> str:
    task_dir = get_task_dir(task_id)
    os.makedirs(task_dir, exist_ok=True)
    return task_dir


def save_task_meta(task_id: str, meta: Dict[str, Any]) -> None:
    meta_file = get_task_meta_file(task_id)
    ensure_task_dir(task_id)
    with open(meta_file, 'w', encoding='utf-8') as f:
        json.dump(meta, f, ensure_ascii=False, indent=2)
python
def append_result_data(task_id: str, data_list: list) -> None:
    result_file = get_task_result_file(task_id)
    ensure_task_dir(task_id)
    with open(result_file, 'a', encoding='utf-8') as f:
        for item in data_list:
            f.write(json.dumps(item, ensure_ascii=False) + '\n')
python
if person_list:
    append_result_data(task_id, person_list)
    total_retrieved += len(person_list)

Technical Analysis

Search results and query metadata are stored beneath the project-level task_data directory as plaintext JSON and JSONL files. The documented response records may include names, employers, countries, job titles, gender, and contact-availability counts.

Directory and file modes are inherited from the process umask rather than being explicitly restricted. The project also provides no retention period, cleanup mechanism, encryption option, or warning that completed datasets remain on disk indefinitely.

The UUID validation prevents direct path traversal through task_id, but it does not protect the confidentiality or lifecycle of the stored records.

Attack Path

  1. A user performs a LinkedIn person search.
  2. The API returns personal and professional records.
  3. append_result_data writes those rec ...[truncated 743 chars]
Remediation
View remediation

Remediation Suggestions

  • Create task_data and per-task directories with mode 0700.
  • Create metadata and result files with mode 0600.
  • Verify ownership, file type, and permissions before reading or appending.
  • Add a documented retention period and automatically delete expired or completed tasks.
  • Provide a user-facing cleanup command for immediate deletion.
  • Minimize stored fields to those required by the user.
  • Consider authenticated encryption for results that must remain on disk.
  • Inform users before persistence and disclose the destination and retention duration.
  • Avoid placing sensitive task data inside a broadly shared or source-controlled project directory.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Open-Ended Dependency Version Allows Uncontrolled Future Releases

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, line 1; installation instruction in SKILL.md, line 21
Vulnerability Type: Unpinned third-party dependency
Risk Level: Medium

Vulnerable Code

text
httpx>=0.23.0
bash
pip install -r requirements.txt

Technical Analysis

The requirement specifies only a minimum version. Consequently, installations may resolve to any future httpx release and to unconstrained transitive dependency versions available through the active pip index.

This makes builds non-reproducible and expands supply-chain exposure. If an upstream account, release, transitive package, or configured package index is compromised, installation may retrieve code that was never reviewed with this Skill. No hashes or lock file are provided to validate downloaded artifacts.

No evidence was found that the currently named httpx package is malicious. The vulnerability is the uncontrolled dependency-resolution policy, not a confirmed malicious package.

Attack Path

  1. A user follows the Skill setup instructions.
  2. Pip resolves httpx>=0.23.0 using the user's configured index and the dependency metadata available at installation time.
  3. A compromised future release, transitive dependency, or untrusted index response is selected.
  4. Pip downloads and installs the unreviewed package artifacts.
  5. Package installation logic or later imports execute attacker-controlled code with the privileges of the user running pip or the Skill.

Impact Assessment

A successful supply-chain compromise could execute arbitrary code with the installing user's privileges and access that user's files, environment variables, API key, and search results. Exploitation requires compromise or manipulation of the selected package source or release; the repository itself contains no confirmed malicious dependency payload.

Remediation
View remediation

Remediation Suggestions

  • Pin httpx to a specifically reviewed version.
  • Generate a lock file that also pins all transitive dependencies.
  • Require cryptographic hashes during installation, for example through pip install --require-hashes.
  • Use a trusted, explicitly configured package index.
  • Periodically update pins through a controlled dependency-review process.
  • Run vulnerability and provenance checks on each dependency update.
  • Install dependencies inside an isolated virtual environment rather than into a privileged or system-wide Python environment.
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description does not mention version-check network requests and local version cache writes that occur independently of the user’s search task. Hidden update-check behavior expands the network and persistence surface and can surprise users in environments expecting only direct search-related activity.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description does not mention version-check network requests and local version cache writes that occur independently of the user’s search task. Hidden update-check behavior expands the network and persistence surface and can surprise users in environments expecting only direct search-related activity.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description does not mention version-check network requests and local version cache writes that occur independently of the user’s search task. Hidden update-check behavior expands the network and persistence surface and can surprise users in environments expecting only direct search-related activity.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill description does not mention version-check network requests and local version cache writes that occur independently of the user’s search task. Hidden update-check behavior expands the network and persistence surface and can surprise users in environments expecting only direct search-related activity.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The skill instructs reading the credential file directly with cat ~/.upkuajing/.env, which can expose the full API key contents to the agent or logs. Direct secret material access is dangerous because it violates least-privilege and increases the chance of accidental disclosure, reuse, or exfiltration during unrelated operations.

Content

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

API密钥与充值

使用此技能需要API密钥。API密钥保存在 ~/.upkuajing/.env 文件中:

bash
cat ~/.upkuajing/.env

文件内容示例:

text

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The workflow tells the agent to inspect the local credential file for the API key and to participate in key provisioning if missing. Combining credential discovery with automatic acquisition and storage broadens the chance of unauthorized secret handling and persistent storage of sensitive tokens without a clearly bounded permission model.

Content

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

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

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

Automatically applying for a new API key and saving it into ~/.upkuajing/.env creates a credential lifecycle action inside a search skill. In the context of a people-search skill that also performs paid operations, this is especially risky because it can silently create or persist account credentials and enable subsequent chargeable API usage.

Content

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

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

### **账户充值**

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

模块文档明确写的是“跨境魔方认证管理”,与技能元数据中的“LinkedIn 人员搜索”相冲突,表明代码来源、目的或打包过程存在明显不一致。这类伪装/错配会降低审查可见性,让高风险认证与付费功能隐藏在低风险技能名义下,增加供应链和误授权风险。

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

该文件实现了 API 密钥申请、账户信息查询、余额查看和充值下单等账号管理/付费能力,与宣称的“LinkedIn 人员搜索”技能用途明显不一致。功能越界会扩大权限与攻击面,使一个本应做搜索的技能具备凭据管理和资金相关操作,一旦被误装、误用或与其他组件联动,可能导致账号滥用、费用损失或数据暴露。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

代码会检查并读取本地 .env 中的 API 密钥,这属于凭据处理行为。在一个与人员搜索不匹配的技能中包含此类逻辑更危险,因为它引入了本地敏感凭据发现与管理能力;若文件权限不当、被其他进程读取或被误提交,密钥可能泄露。

Content

Scanner excerpt · scripts/auth.py (reported line 18)May include surrounding context.

python
"""
    申请新的 API 密钥。
    """
    # 检查是否已存在 .env 文件和 API key
    env_file = UPKUAJING_ENV_FILE

    if env_file.exists():

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

直接打开并读取 .env 文件内容来查找 API 密钥,会使该技能具备本地凭据访问能力。结合本技能表面用途,这种能力超出用户合理预期,提升了供应链场景下的敏感信息暴露风险。

Content

Scanner excerpt · scripts/auth.py (reported line 22)May include surrounding context.

python
env_file = UPKUAJING_ENV_FILE

    if env_file.exists():
        # 读取现有的 .env 文件
        try:
            with open(env_file, 'r', encoding='utf-8') as f:
                content = f.read()

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

代码将新申请的 API 密钥以明文写入 .env 文件,这是典型的不安全凭据存储。明文凭据容易被本地其他用户、备份系统、日志/同步工具或误提交到版本库而泄露,进而导致 API 被盗用和账户损失。

Content

Scanner excerpt · scripts/auth.py (reported line 71)May include surrounding context.

python
"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")

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

创建充值订单属于资金操作能力,与人员搜索场景无直接关系,属于高风险越界功能。即使当前代码只是返回支付地址,这仍可被用于诱导付费、触发未经预期的财务流程,尤其在用户以为安装的是普通搜索技能时更危险。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 19)May include surrounding context.

python
API_BASE_URL = "https://openapi.upkuajing.com"
API_KEY_ENV = "UPKUAJING_API_KEY"
UPKUAJING_DIR = Path.home() / '.upkuajing'
UPKUAJING_ENV_FILE = UPKUAJING_DIR / '.env'
UPKUAJING_LOGS_DIR = UPKUAJING_DIR / 'logs'

# 日志开关

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/auth.py (reported line 78)May include surrounding context.

python
def load_env_file() -> Dict[str, str]:
    """
    从 ~/.upkuajing/.env 文件加载环境变量。

    Returns:
        环境变量字典

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 63)May include surrounding context.

python
def load_env_file() -> Dict[str, str]:
    """
    从 ~/.upkuajing/.env 文件加载环境变量。

    Returns:
        环境变量字典

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 85)May include surrounding context.

python
def load_env_file() -> Dict[str, str]:
    """
    从 ~/.upkuajing/.env 文件加载环境变量。

    Returns:
        环境变量字典

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/common.py (reported line 90)May include surrounding context.

python
def load_env_file() -> Dict[str, str]:
    """
    从 ~/.upkuajing/.env 文件加载环境变量。

    Returns:
        环境变量字典

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements exception telemetry to a platform endpoint, which is materially outside the stated LinkedIn person-search purpose of the skill. Functionality mismatch is dangerous because it can hide undisclosed data flows and operational behaviors that users and integrators would not reasonably expect from a people-search skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares executable capabilities involving environment variables, local file access, writes, and network calls, but does not constrain them with an explicit tool scope. That makes the effective privilege surface broader than what a reviewer or orchestrator can infer from the manifest, increasing the risk of unintended secret access, local persistence, or external communication.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill name, title, and operational description are entirely presented in Chinese, and the instructions throughout the file assume Chinese-language use. There is no indication that users may choose another language or that the Chinese-only constraint is required for a documented regional/compliance reason.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API explicitly supports searching for people based on contactability signals such as phone, WhatsApp, email, website, and social presence, which enables targeted identification and outreach at scale. In a lead-generation/recruiting context, exposing these selectors without any privacy, lawful-basis, anti-harassment, or data-minimization guidance materially increases the risk of misuse for spam, profiling, and non-consensual contact enrichment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Returning demographic attributes such as gender for person search results introduces sensitive profiling capability that can be used for discriminatory targeting in hiring, sales, or outreach workflows. Because the skill is specifically designed to help users find business contacts and decision-makers, the presence of this field without strong restrictions or warnings makes misuse more likely and more harmful.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation instructs callers to upload request parameters, response payloads, and error context for exception reporting, which commonly contain personal data, auth tokens, identifiers, or business-sensitive content. Although it states that sensitive fields will be automatically desensitized, it does not define what is considered sensitive, warn users to minimize submitted data, or prohibit secrets/PII in free-text context fields, creating a realistic risk of unintended data leakage into logging/reporting systems.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
82% confidence
Finding

该规则与上一条实际上指向同一问题:新密钥申请被设计为默认不需要认证。对于一个与技能功能不匹配的模块,这种开放默认值进一步放大了误用和自动化滥用的风险。

Content

Scanner excerpt · scripts/auth.py (reported line 41)May include surrounding context.

python
pass  # 如果读取失败,继续执行

    # 不需要认证申请新密钥
    response = make_request('/agent/auth/create', {}, require_auth=False)

    # 检查是否申请成功
    if response.get('code') != 0:

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