Back to skill

Security audit

Tax Invoice Guard

Security checks for vulnerabilities and agentic risk

Overview

This skill should go to Review because it handles sensitive invoices while overstating tax verification and under-disclosing credential and invoice-data handling.

Install only after review of the publisher and workflow. Treat generated reports as unverified unless actual tax-authority verification is implemented and shown in the output. Do not pass real license keys or confidential invoices through this skill until it documents the yk-global key check, removes raw OCR text and local paths from default output, adds explicit consent for Feishu/tax data sharing, and fixes unchecked invoices being reported as normal.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/duplicate_checker.py:23
Finding
License API Key Exposure Through Command-Line Arguments and External Transmission<![CDATA[ ## Vulnerability Details **File Location**: `scripts/duplicate_checker.py:23-50, 394-409` **Vulnerability Type**: Credential exposure and insecure secret handling **Risk Level**: Medium ### Vulnerable Code ```python VERIFY_URL = "https://api.yk-global.com/v1/verify" def verify_api_key(api_key: str) -> tuple[bool, str]: if not api_key: return False, "FREE" try: req = urllib.request.Request( VERIFY_URL, method="POST", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }, data=b"{}", ) with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read().decode("utf-8")) ``` ```python api_key = "" if len(sys.argv) > 3: arg3 = sys.argv[3] if arg3.startswith("inv-") or arg3.startswith("IN"): api_key = arg3 else: tier_data = json.loads(arg3) monthly_count = tier_data.get("monthly_count", 0) api_key = tier_data.get("api_key", "") if len(sys.argv) > 4 and not api_key: api_key = sys.argv[4] tier = TierConfig.from_api_key(api_key, monthly_count) ``` ### Technical Analysis The script accepts a license API key directly through command-line arguments and sends it as a bearer token to the vendor-controlled `api.yk-global.com` endpoint. External license validation is related to the declared tier-control functionality and does not, by itself, exceed the functional privilege requirements. However, command-line arguments are not an appropriate secret transport mechanism. Depending on the operating environment, arguments may be exposed through: - Process inspection tools such as `ps`. - Shell history. - Process telemetry and audit logging. - Container or orchestration diagnostics. - Parent-process logs and error reports. The network request uses HTTPS, and the audited code does not send invoice records in this request. Never ...[truncated 1027 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove API-key support from positional command-line arguments. 2. Read the credential from a protected environment variable, secret manager, or non-echoing standard-input prompt. 3. If environment variables are used, ensure they are not printed in diagnostics or inherited by unnecessary child processes. 4. Add an explicit offline mode that performs local duplicate checking without contacting the vendor. 5. Clearly document the destination, purpose, and data included in the verification request. 6. Validate the response status, content type, maximum size, and expected JSON schema. 7. Avoid caching complete secret strings where possible; use a keyed or one-way identifier for cache indexing. 8. Support credential revocation and rotation in case a key is exposed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/batch_processor.py:23
Finding
Batch Processor Exposes License API Keys Through Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/batch_processor.py:23-51, 528-552` **Vulnerability Type**: Credential exposure and insecure secret handling **Risk Level**: Medium ### Vulnerable Code ```python VERIFY_URL = "https://api.yk-global.com/v1/verify" def verify_api_key(api_key: str) -> tuple[bool, str]: if not api_key: return False, "FREE" try: req = urllib.request.Request( VERIFY_URL, method="POST", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }, data=b"{}", ) with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read().decode("utf-8")) ``` ```python api_key = "" monthly_processed = 0 if len(sys.argv) > 2: arg2 = sys.argv[2] if arg2.startswith("inv-") or arg2.startswith("IN"): api_key = arg2 else: historical = json.loads(arg2) if len(sys.argv) > 3: arg3 = sys.argv[3] if not api_key and (arg3.startswith("inv-") or arg3.startswith("IN")): api_key = arg3 elif not historical: tier_data = json.loads(arg3) monthly_processed = tier_data.get("monthly_processed", 0) api_key = tier_data.get("api_key", "") if len(sys.argv) > 4: api_key = sys.argv[4] tier = TierConfig.from_api_key(api_key, monthly_processed) ``` ### Technical Analysis The batch processor repeats the unsafe credential-handling pattern from the duplicate checker. A complete bearer credential can be supplied in several positional arguments or embedded in command-line JSON, after which it is transmitted to the vendor verification service. Embedding the key in JSON does not mitigate exposure because the JSON remains part of the process argument vector. The five-minute in-memory cache also uses the complete API key as a dictionary key, unnecessarily preserving it in process memory. The request body i ...[truncated 953 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all positional API-key parsing. 2. Accept secrets only through a documented secret manager, protected environment variable, or non-echoing standard input. 3. Do not use the complete API key as a cache dictionary key; use a keyed digest or avoid credential caching. 4. Add an explicit user-controlled offline mode. 5. Inform users before making the vendor request and document precisely what is transmitted. 6. Implement bounded response reading and strict response-schema validation. 7. Ensure exceptions and debug output never include authorization headers. 8. Provide revocation and rotation procedures for exposed credentials. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/batch_processor.py:608
Finding
Batch Output Discloses Complete OCR Text and Local File Paths<![CDATA[ ## Vulnerability Details **File Location**: `scripts/batch_processor.py:168-190, 284-305, 608-612` **Vulnerability Type**: Sensitive information exposure through output serialization **Risk Level**: Medium ### Vulnerable Code ```python @dataclass class InvoiceRecord: invoice_code: str = "" invoice_no: str = "" invoice_type: str = "" date: str = "" amount: float = 0.0 tax_amount: float = 0.0 buyer_name: str = "" buyer_tax_id: str = "" seller_name: str = "" seller_tax_id: str = "" items: str = "" file_path: str = "" file_type: str = "" raw_text: str = "" status: str = "pending" verify_status: str = "unchecked" notes: str = "" def to_dict(self): d = asdict(self) d["fields_hash"] = self.fields_hash() return d ``` ```python record = InvoiceRecord(raw_text=text, file_path=file_path) ``` ```python output = { "summary": summary, "records": [r.to_dict() for r in records], } print(json.dumps(output, ensure_ascii=False, indent=2)) ``` ### Technical Analysis `InvoiceRecord.to_dict()` serializes every dataclass field through `asdict()`. Consequently, the batch result contains both `raw_text` and `file_path`. Raw OCR text may contain substantially more information than the fields needed for duplicate detection, including: - Buyer and seller taxpayer identifiers. - Company names and addresses. - Invoice numbers and financial amounts. - Purchased goods or services. - Travel information or passenger details. - Unrelated text accidentally captured by OCR. Local paths can reveal usernames, tenant names, project structure, internal share names, or other filesystem metadata. This behavior contradicts the documentation stating that raw invoice data is processed and immediately discarded. Although the script itself prints to standard output rather than writing a file, application frameworks, agent runners, CI systems, and logging collectors frequently persist s ...[truncated 896 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `asdict()` with an explicit output allowlist containing only fields required by the caller. 2. Exclude `raw_text` and `file_path` from normal output. 3. Make raw-data output available only through an explicit, clearly labeled diagnostic option that defaults to disabled. 4. Redact taxpayer identifiers and other sensitive fields unless the caller explicitly requires them. 5. Clear raw OCR data after parsing when no longer needed. 6. Add retention and logging guidance for all callers. 7. Correct the privacy documentation so it accurately describes actual data handling. 8. Add automated tests asserting that normal output never contains raw OCR text or local paths. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/compliance_report.py:281
Finding
Unchecked Invoices Are Incorrectly Reported as Having Normal Verification Status<![CDATA[ ## Vulnerability Details **File Location**: `scripts/batch_processor.py:441-454, 597-603`; `scripts/compliance_report.py:281-292` **Vulnerability Type**: Fail-open verification logic and misleading security result **Risk Level**: High ### Vulnerable Code ```python def verify_invoice_tax( record: InvoiceRecord, tier: TierConfig, ) -> tuple[str, str]: allowed, msg = tier.allow_verify() if not allowed: return "unchecked", msg # TODO: Call the State Tax Administration verification API. # This is a placeholder; actual integration requires an enterprise account. return "unchecked", "Tax verification API integration placeholder" ``` The report then considers only explicitly abnormal states: ```python abnormal_records = [ r for r in records if r.verify_status in ("void", "red", "失控", "suspicious", "abnormal") ] if not abnormal_records: return """## 四、验真结果 **异常发票数量**:0 张 **异常发票金额**:¥0.00 ✅ 全部发票状态正常。 """ ``` ### Technical Analysis The tax-verification function is a placeholder and always returns `unchecked`, including for Pro-tier users. The report generator excludes `unchecked` records from its abnormal set and interprets an empty abnormal set as evidence that every invoice is normal. The logic conflates two materially different conditions: - No verified invoice was found to be abnormal. - Every invoice was successfully verified and found to be normal. Only the first condition is established. Treating it as the second is a fail-open verification design. This directly conflicts with the advertised official tax-authority verification workflow and can create a false compliance assurance. ### Attack Path 1. An attacker or employee submits a forged, voided, red-flushed, or otherwise invalid invoice. 2. Local duplicate checks do not identify the authenticity problem. 3. `verify_invoice_tax()` performs no external verification and returns `unchecked`. 4. The report excludes the record because `unchecked` i ...[truncated 685 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat `unchecked` as a separate first-class status and never present it as `normal`. 2. If any record remains unchecked, state clearly that official verification was not performed or was incomplete. 3. Calculate and display separate counts for verified-normal, verified-abnormal, unchecked, and verification-failed records. 4. When the user explicitly requests official verification, fail closed if the integration is unavailable. 5. Remove or qualify claims of real-time official verification until a working, authenticated integration is implemented. 6. Require positive evidence from the verification provider before assigning `normal`. 7. Record verification timestamps, provider identity, response identifiers, and non-sensitive audit evidence. 8. Add regression tests proving that batches containing only `unchecked` records cannot produce an “all normal” conclusion. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/compliance_report.py:256
Finding
Unescaped Invoice Fields Permit Markdown and Feishu Report Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/compliance_report.py:151-170, 256-271, 544-554, 621-632` **Vulnerability Type**: Output injection through unsafe markup generation **Risk Level**: Medium ### Vulnerable Code ```python ent_name = buyer_name or "(未提供)" ent_tax_id = buyer_tax_id or "(未提供)" rows = [ f"| 项目 | 内容 |", f"|------|------|", f"| 报告期间 | {datetime.now().strftime('%Y-%m-%d')} ~ {datetime.now().strftime('%Y-%m-%d')} |", f"| 发票总数 | {summary.total_invoices} 张 |", f"| 价税合计总额 | {_fmt_currency(summary.total_amount)} |", f"| 异常发票数 | {abnormal_count} 张 |", f"| 涉及企业名称 | {ent_name} |", f"| 纳税人识别号 | {ent_tax_id} |", ] ``` ```python invoice_no = r.invoice_no or "(无号码)" date = _fmt_date(r.date) seller = r.seller_name or "(无销售方)" rows.append( f"| {i} | {invoice_no} | {date} | " f"{_fmt_currency(amount)} | {seller} | {reason} |" ) ``` The same pattern is used by the Feishu report generator: ```python lines.append(f"| 涉及企业名称 | {ent_name} |") lines.append(f"| 纳税人识别号 | {ent_tax_id} |") ``` ```python dup_rows.append( f"| {i} | {invoice_no} | {date} | " f"{_fmt_currency(amount)} | {seller} | {reason} |" ) ``` ### Technical Analysis OCR-derived invoice fields and caller-supplied company values are interpolated directly into Markdown and Lark-flavored markup. There is no escaping or validation for: - Pipe characters that create additional table columns. - Newlines that terminate the current row. - Markdown links and images. - Headings, block quotes, and task lists. - HTML-like or Lark-specific tags such as callouts. - Bidirectional or invisible control characters. - Excessively long content. A malicious invoice can place crafted markup in a seller or buyer name. When the report is rendered locally or sent to Feishu, the injected value may alter the apparent report structure, insert phishing links, create fabricated findings, or obscure legitimate content. The code does not execute injected ma ...[truncated 1228 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Implement a centralized escaping function for every untrusted value inserted into Markdown tables. 2. Escape pipe characters, backslashes, line breaks, Markdown control characters, and HTML-like delimiters. 3. Strip or encode Feishu-specific tags from untrusted content. 4. Permit only safe URL schemes and avoid automatically rendering links from OCR-derived fields. 5. Normalize or reject bidirectional and invisible control characters. 6. Apply strict length limits and field-specific character validation to invoice numbers, tax identifiers, dates, and names. 7. Keep data separate from presentation where the target API supports structured document blocks. 8. Add tests using malicious seller names containing pipes, newlines, links, headings, and callout tags. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A second description-behavior mismatch confirms that key controls—official verification, reporting, upload/scan recognition, and batch handling—may not exist, while undeclared network access to api.yk-global.com is present. In an invoice compliance skill, false assurances are particularly dangerous because users may rely on the tool to approve reimbursements or detect fraud when no real verification occurred.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A second description-behavior mismatch confirms that key controls—official verification, reporting, upload/scan recognition, and batch handling—may not exist, while undeclared network access to api.yk-global.com is present. In an invoice compliance skill, false assurances are particularly dangerous because users may rely on the tool to approve reimbursements or detect fraud when no real verification occurred.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The script sends supplied API keys to an external domain unrelated to the stated duplicate-detection function, which is a direct secret-transmission behavior. In invoice-processing contexts, this is especially risky because users may assume local handling of sensitive workflows; exfiltration of API keys to a third party can enable account misuse, tracking, or broader compromise if those keys are reused or trusted elsewhere.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The trigger words include broad, common finance terms like 'invoice,' 'duplicate,' 'reimbursement,' and 'compliance,' which can cause the skill to activate in ordinary conversations unrelated to the user's intent. In this context, accidental invocation is more dangerous because the skill handles sensitive financial documents and can route data into verification workflows or external collaboration platforms.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README promotes creation of shareable Feishu documents and import of invoice details into Feishu Bitable without an explicit warning that this discloses potentially sensitive invoice, tax ID, and reimbursement data to external systems and collaborators. Because the output is described as shareable/commentable, the risk includes unintended broad access, data leakage, and compliance violations for financial records.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The README claims 'No invoice raw data storage: Processed and discarded immediately,' but the documented functionality includes writing compliance reports to local files and exporting invoice details to Feishu Bitable. Even if raw binaries are discarded, extracted invoice fields and generated reports still contain sensitive financial/tax data, so the claim can mislead users into disclosing regulated information under false assumptions about retention and persistence.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The README claims 'No invoice raw data storage: Processed and discarded immediately,' but the documented functionality includes writing compliance reports to local files and exporting invoice details to Feishu Bitable. Even if raw binaries are discarded, extracted invoice fields and generated reports still contain sensitive financial/tax data, so the claim can mislead users into disclosing regulated information under false assumptions about retention and persistence.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill advertises network-dependent behavior such as tax authority verification and Feishu document creation, but does not declare any tool scope or allowed-tools boundary. Missing scope declarations make external data transmission less transparent and weaken least-privilege controls, especially for invoice data that may contain sensitive financial and tax identifiers.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Broad trigger terms like 'invoice', 'duplicate', 'compliance', or 'verification' can cause the skill to activate in unrelated contexts and process sensitive documents unintentionally. For a finance-oriented skill, accidental invocation raises the chance of unnecessary extraction, transmission, or retention of confidential invoice and tax data.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill omits a prominent warning that invoice contents may be transmitted to external tax authority systems and Feishu services. Because invoices commonly contain company identifiers, tax IDs, transaction details, and potentially personal information, lack of notice undermines informed consent and can create privacy, compliance, and data-governance issues.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The file states that the compliance report is structured to comply with a specific Chinese regulation, but does not explain that this locale/regulatory scope is limited to China-specific use cases. Because SQP-3 applies to all file types, this natural-language framing can be a policy issue when a skill appears to impose a jurisdiction-specific standard without user choice or explicit scope justification.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The title and content are explicitly scoped to Chinese invoice types and use China-specific invoice terminology and field conventions, but the document does not state that this is a region-specific reference or offer any language/locale choice. Under the policy, locale-specific constraints should be clearly documented and justified when they are mandatory.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documented verification flow sends invoice fields and OCR-derived verification data to an external tax-verification endpoint but does not clearly warn users that invoice data will leave the system. Invoice metadata can contain sensitive financial, tax, and business information, so silent transmission creates a privacy and compliance risk, especially in reimbursement or enterprise contexts.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The code sends API keys to api.yk-global.com for tier validation, but that external dependency is not clearly tied to the stated invoice-processing function. This creates an unnecessary trust boundary and exposes user secrets to a third party, which is especially concerning in a financial-compliance skill where users may assume credentials are only used locally or with tax-authority systems.

External Transmission

Medium
Category
Data Exfiltration
Content
# ─────────────────────────────────────────────────────────────────────────────
# Token Verification (2026-04-22: mandatory per MEMORY.md)
# ─────────────────────────────────────────────────────────────────────────────
VERIFY_URL = "https://api.yk-global.com/v1/verify"
_cache: Dict[str, tuple[bool, str, float]] = {}  # key -> (is_pro, tier, expiry)
CACHE_TTL = 300  # 5 minutes
Confidence
88% confidence
Finding
This file hardcodes an external verification endpoint and uses it for outbound communication, introducing data egress from a financial-document processing workflow. In context, external transmission is more sensitive because invoice systems commonly handle enterprise identifiers and credentials, so unexpected outbound calls increase supply-chain and privacy risk.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The Authorization bearer token is transmitted to a remote service without any user-facing notice or consent at the call site. Silent credential transmission is risky because users of a compliance tool may supply sensitive enterprise API keys, and those secrets could be logged, retained, or misused by the remote service if compromised or untrusted.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The skill advertises official tax-authority verification, but the implementation is only a placeholder that always returns "unchecked" and never performs real validation. In an invoice-compliance tool, this can mislead users into trusting invoices as having gone through authoritative verification when they have not, creating a security and fraud-detection gap.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This code’s user-facing natural-language content is entirely fixed in Chinese, beginning with the module description and continuing throughout generated reports and CLI usage strings. The file does not indicate that users can opt into another language, which can violate a language/locale policy when a skill is expected to respect user language preferences.

Intent-Code Divergence

Medium
Confidence
99% confidence
Finding
The module-level documentation promises image similarity as part of duplicate detection, yet the actual duplicate-check logic only evaluates code/number equality and field-hash matching, with no image comparison over image_hash or image content. This is an active contradiction between documented intent and implemented behavior.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
This module mixes invoice-duplicate detection with external API-key verification and tier enforcement, creating an unexpected networked capability in code that otherwise processes invoice data locally. In a security-sensitive invoice workflow, hidden or unnecessary external verification expands the attack surface, can leak operational metadata, and violates least-privilege/separation-of-concerns expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
# ─────────────────────────────────────────────────────────────────────────────
# Token Verification (2026-04-22: mandatory per MEMORY.md)
# ─────────────────────────────────────────────────────────────────────────────
VERIFY_URL = "https://api.yk-global.com/v1/verify"
_cache: dict = {}  # key -> (is_pro, tier, expiry)
CACHE_TTL = 300  # 5 minutes
Confidence
94% confidence
Finding
The presence of a hardcoded external verification endpoint indicates this script has outbound network capability unrelated to core duplicate analysis. In the context of invoice and reimbursement handling, unexpected external transmission is more dangerous because the system likely processes sensitive financial records and operators may not expect any third-party contact from this component.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code transmits API keys to an external verification service without any in-band disclosure, warning, or opt-in, which is unsafe handling of secrets. Even when using HTTPS, undisclosed secret transmission is dangerous because users and integrators cannot make informed trust decisions, and sensitive invoice-processing systems often require strict data-flow transparency.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The function documentation states triple-check behavior, but within the function there is no third image-based similarity stage despite the documented expectation. The implemented logic returns based on code/number match or key-field hash only, so the documentation overstates the detection method.

Context-Inappropriate Capability

Low
Confidence
95% confidence
Finding
The changelog unnecessarily discloses operational infrastructure details, including a public deployment server IP and relationships between service/payment systems. While not an exploit by itself, this information aids reconnaissance, targeting, and social-engineering against the service, and it is unrelated to the invoice-processing feature set.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The document centers exclusively on the State Tax Administration platform, a Chinese government domain, and CNY invoice parameters, which imposes a specific locale and regulatory context. The file does not explicitly frame this as a China-only skill or otherwise document the locale constraint for users.

Static analysis

No suspicious patterns detected.