Back to skill

Security audit

飞书个人记账(含面板app)

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to do Feishu accounting setup and bookkeeping, but it asks for broad Feishu access and handles App Secrets in ways that can leak them.

Install only if you are comfortable granting this skill broad Feishu Base permissions and storing a long-lived App Secret locally. Use a least-privilege Feishu app if possible, avoid pasting secrets into chat/logs, rotate any secret already used with this workflow, verify or build the APK yourself, and manually confirm parsed receipt data before recording it.

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
scripts/apply_permissions.py:35
Finding

Feishu Application Receives Permissions Beyond the Skill's Operational Requirements

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/setup_bitable.py:107
Finding

App Secret Is Exposed Through Command Arguments, Standard Output, Chat, Plaintext Files, and APK Local Storage

Content
View full analysis
/path/to/feishu-accounting/.env << 'EOF' FEISHU_APP_ID=你的App_ID FEISHU_APP_SECRET=你的App_Secret FEISHU_BASE_TOKEN=你的Base_Token FEISHU_DETAIL_TABLE_ID=你的明细表ID EOF ``` The optional APK architecture also specifies plaintext browser-style persistence: ```text 1. Login → input App ID / Secret / Base Token / Table ID → store in localStorage 2. init() → getToken() → fetchAll() → retrieve all detail records ``` ### Technical Analysis Secrets passed as command-line argum ...[truncated 2765 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:124
Finding

Mutable Prebuilt APK Is Recommended Without Integrity or Provenance Verification

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cleanup_bitable.py:67
Finding

Bulk Cleanup Utility Irreversibly Deletes Remote Records Without Confirmation or Dry-Run Protection

Content
View full analysis
0 else "ℹ️ 表中没有记录") break print(f" 第{batch}页 (offset={offset}): {len(records)} 条", end="") deleted = 0 for rec_id in record_ids: time.sleep(0.1) if delete_record(token, args.base_token, target["id"], rec_id): deleted += 1 else: print(" ⚠️ 删除失败") total_deleted += deleted print(f" → 删了 {deleted} 条") offset += len(records) print(f"\n✅ 总计清理 {total_deleted} 条记录") ``` ### Technical Analysis The utility selects the first table whose name exactly match ...[truncated 2044 chars]
Remediation
View remediation
` - `--confirm-table-id ` 4. For interactive use, require the operator to type the full table ID or a generated confirmation phrase. 5. Verify expected schema fields before considering the table eligible for cleanup. 6. Export all records to a timestamped backup before deletion. 7. Prefer batch deletion with an auditable operation identifier if the Feishu API supports it. 8. Log the Base Token in redacted form, table ID, record count, initiator, and timestamp without logging application secrets. 9. Abort when more than one table has the requested name rather than silently selecting the first match. 10. Document recovery procedures and retention expectations. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (41)

Tainted flow: 'req' from os.environ.get (line 131, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/record_bill.py (reported line 103)May include surrounding context.

python
url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
    data = json.dumps({"app_id": FEISHU_APP_ID, "app_secret": FEISHU_APP_SECRET}).encode("utf-8")
    req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=15) as resp:
        result = json.loads(resp.read())
    if result.get("code") != 0:
        raise RuntimeError(f"获取 Tenant Token 失败: {result}")

Tainted flow: 'req' from os.environ.get (line 272, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/record_bill.py (reported line 135)May include surrounding context.

python
"Authorization": f"Bearer {token}", "Content-Type": "application/json",
    }, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
            if result.get("code") == 0:
                return {"success": True}

Tainted flow: 'req' from os.environ.get (line 272, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/record_bill.py (reported line 273)May include surrounding context.

python
"Authorization": f"Bearer {token}", "Content-Type": "application/json",
    }, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
            if result.get("code") == 0:
                return {"success": True}

Tainted flow: 'req_fields' from os.environ.get (line 253, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/record_bill.py (reported line 254)May include surrounding context.

python
url_fields = (f"https://open.feishu.cn/open-apis/base/v3/bases/{base}"
                      f"/tables/{tbl}/fields")
        req_fields = urllib.request.Request(url_fields, headers={"Authorization": f"Bearer {token}"})
        with urllib.request.urlopen(req_fields, timeout=15) as resp:
            fields_data = json.loads(resp.read())
        field_map = {}
        for f in fields_data.get("data", {}).get("fields", []):

Tainted flow: 'del_req' from os.environ.get (line 319, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/record_bill.py (reported line 321)May include surrounding context.

python
f"/tables/{tbl}/records/{rid}")
        del_req = urllib.request.Request(del_url, method="DELETE",
                                         headers={"Authorization": f"Bearer {token}"})
        with urllib.request.urlopen(del_req, timeout=15) as resp:
            del_r = json.loads(resp.read())
        if del_r.get("code") == 0:
            return {"success": True, "record_id": rid}

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The overview claims a complete two-stage package and emphasizes a permanent-token synchronization model, but the supplied behavior centers on setup/admin actions and dynamic token retrieval. This inconsistency is security-relevant because it obscures actual privileged operations and can defeat informed consent during deployment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The overview claims a complete two-stage package and emphasizes a permanent-token synchronization model, but the supplied behavior centers on setup/admin actions and dynamic token retrieval. This inconsistency is security-relevant because it obscures actual privileged operations and can defeat informed consent during deployment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The overview claims a complete two-stage package and emphasizes a permanent-token synchronization model, but the supplied behavior centers on setup/admin actions and dynamic token retrieval. This inconsistency is security-relevant because it obscures actual privileged operations and can defeat informed consent during deployment.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The overview claims a complete two-stage package and emphasizes a permanent-token synchronization model, but the supplied behavior centers on setup/admin actions and dynamic token retrieval. This inconsistency is security-relevant because it obscures actual privileged operations and can defeat informed consent during deployment.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation directs plaintext handling of App Secret and other credentials without adequate warnings about sensitivity, storage risks, or least-privilege alternatives. This is dangerous because users may normalize insecure secret management for tokens that can authorize broad Feishu operations.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill creates a natural-language credential exposure workflow by telling the agent to restate user-supplied secrets and save them locally in plaintext. This is more dangerous than ordinary config handling because chat transcripts and agent logs become additional secret exposure surfaces.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The explicit instruction to create a .env file containing App ID, App Secret, and table tokens is direct credential access and storage in plaintext. If the host, repository, backups, or logs are exposed, these credentials can be reused to access or modify Feishu resources.

Content

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

bash
# 在技能目录创建 .env(record_bill.py 会自动从同目录读取)
cat > /path/to/feishu-accounting/.env << 'EOF'
FEISHU_APP_ID=你的App_ID
FEISHU_APP_SECRET=你的App_Secret
FEISHU_BASE_TOKEN=你的Base_Token

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The usage triggers are overly broad and allow normal phrases or even image upload alone to initiate bookkeeping actions. Because the skill can write local files and sync to Feishu, loose triggering materially increases the risk of unauthorized or accidental data modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly instructs automatic writes based on OCR/vision results from receipts without any confirmation warning. In financial software, this is especially risky because model mistakes directly alter user records and could be abused with crafted images to poison data.

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 · references/feishu-base-api-pitfalls.md (reported line 74)May include surrounding context.

python
# ❌ 错误:setdefault 不覆盖已存在的环境变量
# 如果父 shell 已有 FEISHU_APP_ID(旧应用的),.env 的值会被忽略
os.environ.setdefault(k.strip(), v.strip())

# ✅ 正确:直接赋值,.env 始终优先

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 · references/feishu-base-api-pitfalls.md (reported line 77)May include surrounding context.

python
# ❌ 错误:setdefault 不覆盖已存在的环境变量
# 如果父 shell 已有 FEISHU_APP_ID(旧应用的),.env 的值会被忽略
os.environ.setdefault(k.strip(), v.strip())

# ✅ 正确:直接赋值,.env 始终优先

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/record_bill.py (reported line 88)May include surrounding context.

python
```python
# ❌ 错误:setdefault 不覆盖已存在的环境变量
# 如果父 shell 已有 FEISHU_APP_ID(旧应用的),.env 的值会被忽略
os.environ.setdefault(k.strip(), v.strip())

# ✅ 正确:直接赋值,.env 始终优先

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/record_bill.py (reported line 95)May include surrounding context.

python
```python
# ❌ 错误:setdefault 不覆盖已存在的环境变量
# 如果父 shell 已有 FEISHU_APP_ID(旧应用的),.env 的值会被忽略
os.environ.setdefault(k.strip(), v.strip())

# ✅ 正确:直接赋值,.env 始终优先

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
def get_tenant_token(app_id: str, app_secret: str) -> str:
    """获取 Tenant Access Token"""
    url = f"{FEISHU_HOST}/open-apis/auth/v3/tenant_access_token/internal"
    data = json.dumps({"app_id": app_id, "app_secret": app_secret}).encode("utf-8")
    req = urllib.request.Request(

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/apply_permissions.py (reported line 21)May include surrounding context.

python
def get_tenant_token(app_id: str, app_secret: str) -> str:
    """获取 Tenant Access Token"""
    url = f"{FEISHU_HOST}/open-apis/auth/v3/tenant_access_token/internal"
    data = json.dumps({"app_id": app_id, "app_secret": app_secret}).encode("utf-8")
    req = urllib.request.Request(

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

python
def get_tenant_token(app_id: str, app_secret: str) -> str:
    """获取 Tenant Access Token"""
    url = f"{FEISHU_HOST}/open-apis/auth/v3/tenant_access_token/internal"
    data = json.dumps({"app_id": app_id, "app_secret": app_secret}).encode("utf-8")
    req = urllib.request.Request(

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The script automatically loads secrets from a .env file located relative to the skill directory and injects them into the process environment without validating file ownership, permissions, or trust boundary. In an agent skill context, this increases the chance of credential misuse or unintended secret exposure, especially if the skill directory is shared, synced, or writable by other components.

Content

Scanner excerpt · scripts/record_bill.py (reported line 31)May include surrounding context.

python
from datetime import date, datetime
from pathlib import Path

# ── 自动加载 skill 目录下的 .env ──────────────────────────────────────────
_SKILL_ENV = Path(__file__).parent.parent / ".env"
if _SKILL_ENV.exists():
    for line in _SKILL_ENV.read_text().splitlines():

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The .env path is hardcoded to the parent skill directory, encouraging local plaintext credential storage in a predictable location. Predictable, automatic secret loading makes it easier for other local processes, backups, or repository mistakes to expose Feishu credentials that grant remote data access.

Content

Scanner excerpt · scripts/record_bill.py (reported line 32)May include surrounding context.

python
from pathlib import Path

# ── 自动加载 skill 目录下的 .env ──────────────────────────────────────────
_SKILL_ENV = Path(__file__).parent.parent / ".env"
if _SKILL_ENV.exists():
    for line in _SKILL_ENV.read_text().splitlines():
        line = line.strip()

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script prints the Feishu App Secret directly to stdout, which can leak into terminal scrollback, shell history capture, CI/CD logs, remote session transcripts, or agent telemetry. In an agent skill context, stdout is often collected and forwarded, making secret disclosure more dangerous than in an isolated local script.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The machine-readable JSON includes the App Secret, which enables downstream systems, logs, parsers, or other agents to ingest and potentially persist the credential automatically. Because this output is specifically structured for AI parsing, it materially increases the likelihood of silent credential propagation and compromise.

Content

No source excerpt is available for this finding.