Back to skill

Security audit

KSeF Accountant (Polish)

Security checks for vulnerabilities and agentic risk

Overview

This instruction-only KSeF accounting skill is mostly purpose-aligned, but it needs Review because some examples encourage automatic accounting changes and running unpinned external code in a sensitive financial context.

Before installing, treat this as reference material only. Do not provide production KSeF credentials unless the platform shows the secret and disable-model-invocation controls are enforced. Require human approval before sending invoices, posting accounting entries, or holding payments. Do not run the suggested external GitHub status script without pinning and reviewing it, and harden XML validation and exported register storage before production use.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Warning
Location
references/ksef-troubleshooting.md:448
Finding
Unpinned Remote Repository Is Cloned and Executed<![CDATA[ ## Vulnerability Details **File Location**: `references/ksef-troubleshooting.md:448-450` **Vulnerability Type**: Remote payload retrieval and supply-chain execution **Risk Level**: Medium ### Vulnerable Code ```bash git clone https://github.com/CIRFMF/ksef-latarnia cd ksef-latarnia python check_status.py ``` ### Technical Analysis The troubleshooting procedure clones the current, mutable state of an external Git repository and immediately executes `check_status.py`. It does not pin a reviewed commit or signed release, verify a checksum or signature, inspect the retrieved code, or isolate its execution. Consequently, the code that ultimately runs can change after this Skill has been reviewed. The repository is relevant to KSeF status monitoring and is hosted on a recognizable platform, so the instructions do not establish malicious intent. Nevertheless, this is an unsafe remote-code and supply-chain pattern. The Skill itself is instruction-only and does not automatically execute the commands. Exploitation requires a user or integrating agent to follow the documented procedure. ### Attack Path 1. An attacker compromises the upstream repository, a maintainer account, or an upstream dependency used by `check_status.py`. 2. The attacker modifies the repository’s default branch to include malicious Python code. 3. A user follows the troubleshooting instructions and clones the repository without selecting a trusted revision. 4. The user runs `python check_status.py`. 5. The modified script executes with the privileges and environment of that user. 6. If the process has access to KSeF secrets or accounting files, the malicious code may read or transmit them, modify local files, or perform further network activity. ### Impact Assessment Successful exploitation provides arbitrary code execution under the account that runs the command. The attainable scope is limited by that account’s operating-system permissions and execution environment, but may inc ...[truncated 480 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the mutable default-branch clone with a specific, previously reviewed commit or signed release. 2. Verify the release signature or a publisher-provided cryptographic checksum before execution. 3. Review `check_status.py` and its dependency declarations before running it. 4. Install dependencies from a locked file with hashes rather than accepting mutable dependency versions. 5. Run the utility in a disposable virtual environment or container with: - No KSeF tokens or encryption keys. - A read-only filesystem where practical. - No access to production accounting data. - Restricted outbound network access. - No administrator or root privileges. 6. Prefer an official, documented status endpoint that can be queried directly without executing downloaded code. 7. Clearly warn users that repository content is external code and must not be executed solely because it appears in the Skill documentation. A safer pattern would be: ```bash git clone https://github.com/CIRFMF/ksef-latarnia cd ksef-latarnia git checkout <reviewed-full-commit-hash> git verify-commit <reviewed-full-commit-hash> # Review code and dependencies before execution. python -I check_status.py ``` Commit verification is only effective when the expected signer and commit hash are obtained through a trusted channel. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/ksef-troubleshooting.md:460
Finding
Untrusted XML Is Parsed Without Explicit Entity and Resource Restrictions<![CDATA[ ## Vulnerability Details **File Location**: `references/ksef-troubleshooting.md:460-466` **Vulnerability Type**: Unsafe XML parsing and mutable remote schema retrieval **Risk Level**: Medium ### Vulnerable Code ```python def validate_fa3_xsd(xml_content): """Walidacja względem schematu XSD""" xsd_url = "https://ksef.podatki.gov.pl/xsd/FA3_1-0E.xsd" # Pobierz schemat xsd_doc = etree.parse(xsd_url) schema = etree.XMLSchema(xsd_doc) # Waliduj XML xml_doc = etree.fromstring(xml_content.encode('utf-8')) ``` ### Technical Analysis The example processes potentially untrusted invoice XML using default `lxml.etree` parser behavior. It does not explicitly: - Reject `DOCTYPE` declarations. - Disable DTD loading. - Disable external entity resolution. - Prohibit parser-initiated network access. - Enforce input-size, nesting-depth, or processing-time limits. Depending on the deployed `lxml` and underlying `libxml2` versions and configuration, unsafe entity processing may permit XML External Entity attacks. A malicious document could attempt to reference local files or internal network resources. Excessively large or deeply nested XML and entity-expansion payloads can also consume memory or CPU and cause denial of service. The example additionally retrieves the XSD dynamically from a remote URL on every use. HTTPS protects transport when certificate validation succeeds, but it does not pin the schema to a reviewed version. A compromised origin or unintended upstream schema change could alter validation behavior after review. The Skill does not itself parse XML; this risk arises if a user adopts the conceptual implementation without additional hardening. ### Attack Path 1. An attacker supplies or causes the accounting system to retrieve a crafted invoice XML document. 2. The application passes the attacker-controlled content to `validate_fa3_xsd`. 3. The default parser encounters a malicious DTD, external entity, oversized str ...[truncated 1406 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store a reviewed official XSD locally and pin its SHA-256 digest. 2. Update the schema through a controlled review process rather than retrieving it dynamically during validation. 3. Explicitly reject XML containing a `DOCTYPE` declaration. 4. Configure a hardened parser that disables DTD loading, entity resolution, and network access. 5. Enforce maximum input size before parsing. 6. Apply request timeouts, memory limits, and process-level resource limits where invoices are received from untrusted sources. 7. Keep `lxml` and `libxml2` patched. 8. Do not return raw parser exceptions to untrusted clients or include sensitive expanded data in logs. 9. Consider a dedicated hardened XML processing library or sandboxed validation service. A hardened implementation pattern is: ```python from hashlib import sha256 from lxml import etree MAX_XML_BYTES = 10 * 1024 * 1024 EXPECTED_XSD_SHA256 = "<reviewed-schema-sha256>" def validate_fa3_xsd(xml_content, xsd_path): xml_bytes = xml_content.encode("utf-8") if len(xml_bytes) > MAX_XML_BYTES: raise ValueError("XML input exceeds the permitted size") if b"<!DOCTYPE" in xml_bytes.upper(): raise ValueError("DOCTYPE declarations are not permitted") parser = etree.XMLParser( resolve_entities=False, load_dtd=False, no_network=True, huge_tree=False, recover=False, ) with open(xsd_path, "rb") as schema_file: xsd_bytes = schema_file.read() if sha256(xsd_bytes).hexdigest() != EXPECTED_XSD_SHA256: raise ValueError("Unexpected XSD digest") xsd_doc = etree.fromstring(xsd_bytes, parser=parser) schema = etree.XMLSchema(xsd_doc) xml_doc = etree.fromstring(xml_bytes, parser=parser) schema.assertValid(xml_doc) return True ``` The actual input limit and schema update procedure should be selected according to current official KSeF limits and the application’s operational requirements ...[truncated 5 chars]
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (14)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
**Endpoint:**
```http
DELETE /api/online/Session/Terminate
Authorization: SessionToken {token}
```
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Hidden Instructions

High
Category
Prompt Injection
Content
<SystemInfo>Autonomous KSeF Agent v2.1</SystemInfo>
    </Naglowek>

    <!-- Sprzedawca -->
    <Podmiot1>
        <DaneIdentyfikacyjne>
            <NIP>1234567890</NIP>
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The workflow explicitly allows AI-based cost classification to trigger automatic booking when confidence exceeds 0.8, with direct persistence to the database and no mandatory human verification or control checks. In an accounting/KSeF context, misclassification can create incorrect VAT treatment, wrong ledger postings, and compliance/reporting errors that may propagate into statutory registers.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The skill content is written entirely in Polish and presents its instructions and examples only in that language, with no indication that users may choose another language or locale. Under the stated policy, a language-specific constraint should either be optional or clearly documented as a justified region-specific requirement.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The authentication examples show bearer-like token handling and certificate-based session initialization without any warning against hardcoding secrets, exposing them in prompts, or logging them. In an agent skill context, users or downstream implementations may copy these examples directly, increasing the risk of credential leakage and unauthorized access to KSeF sessions and invoice data.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The helper is presented as pre-send validation for KSeF, but it only checks encoding, parses XML, and searches for required tags and schema strings using raw substring matching. In an accounting/KSeF context, this can mislead users into believing invoices are compliant when structurally invalid, semantically incorrect, or nonconformant with the official FA(3) XSD, leading to submission failures or compliance errors.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
"""
    session = requests.Session()

    # 1. Weryfikuj certyfikat (NIGDY verify=False)
    session.verify = certifi.where()

    # 2. Użyj silnych cipher suites
Confidence
75% confidence
Finding
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
This manifest uses Polish-only natural-language descriptions for the skill and its configuration, which can amount to a language/locale policy violation when no opt-in or language alternative is provided. The file does not state that the skill is intentionally limited to Polish-speaking users or that the locale restriction is required for compliance, so the constraint is not clearly justified.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The description explicitly says the assistant is 'w jezyku polskim' (in Polish), which is a natural-language locale constraint. The file does not offer an alternative language option or indicate user choice, so it constitutes a locale policy issue under the stated rule.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The sales VAT register export writes taxpayer and invoice data to local Excel files without any warning about data handling, storage location, or access controls. In practice this increases the risk of unintended disclosure of sensitive financial and tax data through insecure endpoints, shared folders, or unencrypted files.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The purchase register export similarly writes supplier, invoice, and classification data to local Excel files without warning users about confidentiality or endpoint security implications. This can expose commercial and tax records if the workstation, filesystem, or sharing workflow is not adequately protected.

Missing User Warnings

Low
Confidence
79% confidence
Finding
This markdown file documents operations that transmit and retrieve invoice data, which can affect user data and privacy. While it explains endpoints and workflows, it does not explicitly warn that invoices and related metadata may contain sensitive financial or personal information and should be handled securely.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
This markdown file contains user-facing instructions and examples exclusively in Polish, including headings, warnings, and explanatory text. Under the language/locale policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The text states that 'KSeF uses Polish time (UTC+1/UTC+2)' as an instruction without any user opt-in or explicit locale-selection mechanism. Because this is a natural-language constraint and the file does not clearly present locale choice, it matches the policy category for language/locale requirements.

Static analysis

No suspicious patterns detected.