Back to skill

Security audit

泛微 e-office v11 协同办公系统 OpenAPI

Security checks for vulnerabilities and agentic risk

Overview

This looks like a real e-office API skill, but it can change live business accounts/data and its token handling has weak safeguards.

Install only if you trust the publisher and will connect it to a scoped e-office application account. Use HTTPS-only OA endpoints, avoid administrator credentials unless required, confirm every create/edit/delete action before execution, avoid logging token output, and prefer a test environment or narrowly scoped production credentials.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/get-token.py:43
Finding

Authentication Credentials Can Be Sent to an Untrusted or Insecure Endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/get-token.py:43-64 and scripts/get-token.py:113-128
Vulnerability Type: Insufficient validation of a credential-bearing network destination
Risk Level: High

Vulnerable Code

python
def get_token() -> str:
    """获取访问令牌"""
    base_url = get_env("EOFFICE_BASE_URL")
    agent_id = get_env("EOFFICE_AGENT_ID")
    secret = get_env("EOFFICE_SECRET")
    user = get_env("EOFFICE_USER")

    # 构建 token 获取 URL
    token_url = f"{base_url.rstrip('/')}/api/auth/openapi-token"

    # 构建请求 payload
    payload = {
        "user": user,
        "agent_id": agent_id,
        "secret": secret
    }

    try:
        response = requests.post(
            token_url,
            json=payload,
            headers={"Content-Type": "application/json"},
            timeout=TIMEOUT
        )

The refresh operation follows the same destination-handling pattern:

python
def refresh_token(current_token: str, refresh_token: str) -> str:
    """刷新访问令牌"""
    base_url = get_env("EOFFICE_BASE_URL")

    refresh_url = f"{base_url.rstrip('/')}/api/auth/openapi-refresh-token"

    payload = {
        "token": current_token,
        "refresh_token": refresh_token
    }

    try:
        response = requests.post(
            refresh_url,
            json=payload,
            headers={"Content-Type": "application/json"},
            timeout=TIMEOUT
        )

Technical Analysis

The script sends the application secret, user identifier, agent ID, access token, and refresh token to a URL constructed directly from the operator-controlled EOFFICE_BASE_URL. It does not validate that the scheme is HTTPS, reject embedded URL credentials, restrict the destination to an approved host, or disable HTTP redirects.

Sending the request to an HTTP URL exposes its body to interception or modification by a network-positioned attacker ...[truncated 1887 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse EOFFICE_BASE_URL with urllib.parse.urlsplit before using it.
  2. Require the https scheme and reject plaintext HTTP, URL fragments, embedded usernames or passwords, and malformed hostnames.
  3. Maintain an explicit allowlist of trusted OA hostnames where deployment architecture permits it.
  4. Set allow_redirects=False on authentication and refresh requests. If redirects are operationally required, process them manually and only permit same-origin HTTPS destinations.
  5. Keep TLS certificate verification enabled and document that users must install the correct private certificate authority rather than disabling verification.
  6. Use narrowly scoped OA application credentials and an authorized non-administrator identity unless administrative operations are explicitly required.
  7. Rotate EOFFICE_SECRET and revoke outstanding tokens if an insecure URL or unexpected redirect has previously been used.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get-token.py:99
Finding

Access and Refresh Tokens Can Be Exposed Through Process Output

Content
View full analysis

Vulnerability Details

File Location: scripts/get-token.py:99-102 and scripts/get-token.py:156-157
Vulnerability Type: Sensitive authentication material written to standard output or error
Risk Level: Medium

Vulnerable Code

python
if not token:
    print(f"ERROR: Token not found in response", file=sys.stderr)
    print(f"Response: {json.dumps(result, ensure_ascii=False, indent=2)}", file=sys.stderr)
    sys.exit(1)
python
# 输出 token
print(token)

Technical Analysis

The successful execution path prints the bearer token directly to standard output. Although this is the script's documented interface, standard output is commonly retained by agent transcripts, CI systems, terminal capture tools, process supervisors, diagnostic collectors, and shell wrappers.

The missing-token error path prints the complete parsed authentication response to standard error. The documented response format includes both token and refresh_token. Consequently, an unusual or partial response that lacks the expected access-token field but contains other sensitive authentication data can expose that data in logs.

Bearer tokens provide authority through possession alone. They should therefore be handled as secrets and should not be emitted to channels whose retention and access controls are unknown.

Attack Path

  1. The Skill is run by an agent, CI runner, service manager, or shell wrapper that records standard output and standard error.
  2. On success, the access token is printed and retained in the execution log or transcript.
  3. Alternatively, the server returns a partial or malformed success response containing a refresh token but no token, and the entire response is written to standard error.
  4. A user, service, extension, or attacker with access to the retained logs obtains the token.
  5. The token is replayed against the configured OA API before it expires; a captured refresh token may ...[truncated 682 chars]
Remediation
View remediation

Remediation Suggestions

  1. Integrate token retrieval through an in-memory API rather than a subprocess output channel where possible.
  2. If command-line interoperability requires output, provide an explicit opt-in mode for printing the token and clearly warn that output must not be logged.
  3. Prefer writing the token to a caller-specified file created with owner-only permissions, such as mode 0600, and avoid predictable temporary paths.
  4. Never print complete authentication responses. Redact fields including token, access_token, refresh_token, secret, and authorization headers before diagnostic output.
  5. Configure agent runners, CI systems, and service managers to suppress or mask credential-bearing output.
  6. Revoke exposed tokens and rotate refresh tokens if prior execution logs were accessible to unauthorized parties.

T08 · Insecure Dependencies

Note
Location
README.md:20
Finding

Third-Party Dependency Is Installed Without Version or Integrity Pinning

Content
View full analysis

Vulnerability Details

File Location: README.md:20
Vulnerability Type: Unpinned and unverifiable dependency installation
Risk Level: Low

Vulnerable Code

bash
pip install requests

Technical Analysis

The installation instructions resolve requests from the active pip package index without a version constraint, lock file, or cryptographic hash. This makes installations non-reproducible and allows the installed artifact to change independently of the audited Skill package.

The dependency name is legitimate and no malicious package is embedded in the project. The risk arises from relying on the user's current pip index configuration and the latest available compatible release without integrity verification. A compromised package index, malicious mirror, altered pip configuration, or future compromised release could introduce code that executes during installation or when imported by scripts/get-token.py.

Attack Path

  1. An attacker compromises or controls the pip index or mirror configured in the target environment, or alters that environment's pip configuration.
  2. The user follows the documented pip install requests command.
  3. Pip resolves and installs an attacker-controlled or otherwise unaudited artifact because no exact version or hash is required.
  4. Malicious code executes during package installation or when get-token.py imports requests.
  5. The malicious dependency reads environment variables containing EOFFICE_SECRET, user identity, and agent ID, or intercepts tokens processed by the script.

Impact Assessment

Dependency code executes with the privileges of the user running pip or the token script. It could access that user's files, environment variables, network connectivity, and OA credentials. If installation is performed in a privileged global environment, the potential local-system scope increases accordingly.

Within this Skill's context, a compromised depen ...[truncated 144 chars]

Remediation
View remediation

Remediation Suggestions

  1. Declare an audited, exact dependency version in a requirements or lock file.
  2. Generate and verify cryptographic hashes, for example by using pip install --require-hashes -r requirements.txt.
  3. Document the trusted package index explicitly and use HTTPS with normal certificate verification.
  4. Install dependencies inside a dedicated, non-privileged virtual environment rather than into the global Python environment.
  5. Periodically review and update the pinned version through a controlled dependency-update process that includes security scanning and testing.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

声明描述的是一个面向多个企业 OA 业务域的综合 OpenAPI 技能,但提供的代码片段实际只负责访问令牌获取/刷新这一前置认证能力。它不会执行用户管理、部门管理、审批、考勤等任何业务操作。虽然 token 获取可视为这些 API 的支持性基础功能,但如果将该代码块作为技能实际行为的代表,则其主功能明显比声明范围窄,存在描述与实际行为不一致。未发现额外越权或无关资源访问;不匹配主要体现在声明能力远多于实际实现。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README states that the skill can operate approval workflows, modeling data, and file attachments, all of which may impact business records, uploaded files, or operational processes. However, the description does not warn users that these actions may modify production OA data or require appropriate authorization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README advertises creating, editing, and deleting users, which can directly affect account access and organizational data, but it does not provide any warning about the consequences of these operations. For markdown files, missing disclosures about actions that can affect user data or system integrity should be flagged.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 105)May include surrounding context.

md
Agent: 我来帮你查询姓张的研发部员工...

curl -X POST "https://oa.example.com/server/api/hrm/lists" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"search": {"user_name": ["张", "like"]}}'

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill requires environment variables and instructs network access but does not declare any explicit tool scope or permission boundaries. In an agent ecosystem, missing scope declarations can cause the skill to be invoked with broader capabilities than intended, increasing the chance of unauthorized outbound requests or secret use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger language is very broad, including essentially any OA-related task, which can cause unintended invocation on sensitive enterprise requests. In this context, accidental routing to a skill that can access internal user, department, workflow, and attendance data increases the risk of over-collection, inappropriate actions, or data disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

查询用户列表

bash
curl -X GET "$EOFFICE_BASE_URL/api/hrm/lists" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"page": 1, "limit": 10}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill documents destructive user-management actions such as deletion without stating that explicit user confirmation, authorization checks, or safety interlocks are required. In an enterprise OA context, this can enable accidental or unauthorized account deletion, leading to denial of access, workflow disruption, and audit issues.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

该 markdown 文档详细说明了认证与刷新令牌流程,并展示了敏感凭证字段。虽然这是接口说明,但缺少对密钥、访问令牌和刷新令牌保密性的任何明确提醒,可能导致调用方在日志、示例代码或共享环境中不当暴露凭证。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

这是一个 markdown 文件,因此应检查是否缺少会影响用户数据或系统完整性的行为警告。文档直接给出删除接口,且还说明支持批量删除,但没有任何关于数据不可恢复、权限要求或误删风险的提示,容易导致使用者低估影响。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script explicitly prints the obtained access token to stdout, which can expose a sensitive credential to shell history, terminal logs, CI job logs, or calling processes that capture output. In an API-integration skill, this is more dangerous because tokens are bearer credentials and disclosure can directly enable unauthorized API access until the token expires or is revoked.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/get-token.py (reported line 59)May include surrounding context.

python
}

    try:
        response = requests.post(
            token_url,
            json=payload,
            headers={"Content-Type": "application/json"},

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/get-token.py (reported line 123)May include surrounding context.

python
}

    try:
        response = requests.post(
            refresh_url,
            json=payload,
            headers={"Content-Type": "application/json"},

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The skill instructs token retrieval using sensitive credentials from environment variables but provides no warning about secure storage, log exposure, or limiting credential handling. While common in API integrations, omission of credential-safety guidance raises the chance of secrets being mishandled in prompts, terminal history, or logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

对于 markdown 文件,若描述的行为可能影响用户数据、隐私或系统完整性,应有相应提醒。这里说明了附件上传能力,但没有任何关于敏感文件、访问控制或数据处理范围的警示,用户可能在缺乏提示下上传受保护内容。

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.