Back to skill

Security audit

OPC全领域指南

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent OPC UA guide, but it includes under-scoped industrial security shortcuts and a helper script with local file overwrite risk.

Install only if you are comfortable reviewing OPC UA security guidance yourself. Treat None security mode, automatic certificate trust, and untrusted-certificate acceptance as isolated lab shortcuts only, never production defaults. Run package installs in a virtual environment or container with reviewed versions, and avoid passing untrusted common-name values to the certificate helper.

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 (2)

T08 · Insecure Dependencies

Warning
Location
references/opc-ua-setup.md:58
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: references/opc-ua-setup.md:58-63, references/opc-ua-setup.md:158-161, references/opc-ua-tools.md:49-52, references/opc-ua-tools.md:59-62, and references/opc-ua-tools.md:87-90
Vulnerability Type: Supply-chain exposure through unpinned package installation
Risk Level: Medium

Vulnerable Code

references/opc-ua-setup.md:58-63:

bash
### Installation

```bash
pip install opcua-asyncio
# Or the older version
pip install opcua
text

`references/opc-ua-setup.md:158-161`:

```bash
### Installation

```bash
npm install node-opcua
text

The same unpinned commands are repeated in `references/opc-ua-tools.md`.

### Technical Analysis

The installation instructions do not specify exact dependency versions, package hashes, lockfiles, or a trusted registry. Consequently, package resolution depends on mutable registry state and the user's package-manager configuration at installation time.

Running `pip install opcua-asyncio`, `pip install opcua`, or `npm install node-opcua` can select a future release that was not present during this audit. It may also select packages from an attacker-controlled registry if the local pip or npm configuration has been modified. Package installation and subsequent imports can execute package-controlled code with the privileges of the invoking user.

The package names are established OPC ecosystem dependencies, and the project does not itself point to an explicitly malicious source. The risk arises from the absence of reproducible dependency constraints and integrity validation.

### Attack Path

1. An attacker compromises a named package, one of its transitive dependencies, or a package registry used by the victim.
2. Alternatively, an attacker changes the victim's pip or npm registry configuration to prioritize an attacker-controlled source.
3. The user or Agent follows the Skill's installation guidance and exe
...[truncated 845 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every dependency to a reviewed exact version, such as opcua-asyncio==X.Y.Z, opcua==X.Y.Z, and node-opcua@X.Y.Z.
  2. Maintain lockfiles for supported examples and development environments.
  3. For Python, publish a hash-locked requirements file and install it using pip install --require-hashes -r requirements.txt.
  4. For Node.js, commit a reviewed lockfile and recommend npm ci instead of unconstrained installation.
  5. Document the expected official package registry and warn users not to install from unknown mirrors.
  6. Run installations in an isolated virtual environment or container using a non-privileged account.
  7. Add dependency scanning and update review procedures before changing pinned versions.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/opc_utils.py:170
Finding

Path Traversal and Unsafe File Overwrite in Certificate Generation

Content
View full analysis

Vulnerability Details

File Location: scripts/opc_utils.py:170-180, scripts/opc_utils.py:201-226, and scripts/opc_utils.py:422-425
Vulnerability Type: Unsanitized filename construction and unsafe file overwrite
Risk Level: Medium

Vulnerable Code

scripts/opc_utils.py:170-180:

python
out = Path(output_dir)
out.mkdir(parents=True, exist_ok=True)

cert_pem = out / f"{common_name}_cert.pem"
key_pem = out / f"{common_name}_key.pem"
cert_der = out / f"{common_name}_cert.der"
key_der = out / f"{common_name}_key.der"

subject = f"/CN={common_name}/O={org}/C={country}"

scripts/opc_utils.py:201-226:

python
# Generate private key
subprocess.run(
    ["openssl", "genrsa", "-out", str(key_pem), "2048"],
    check=True, capture_output=True, text=True,
)

# Generate self-signed certificate
subprocess.run(
    ["openssl", "req", "-new", "-x509",
     "-key", str(key_pem),
     "-out", str(cert_pem),
     "-days", str(days),
     "-subj", subject],
    check=True, capture_output=True, text=True,
)

# Export DER format
subprocess.run(
    ["openssl", "x509", "-in", str(cert_pem),
     "-outform", "der", "-out", str(cert_der)],
    check=True, capture_output=True, text=True,
)
subprocess.run(
    ["openssl", "rsa", "-in", str(key_pem),
     "-outform", "der", "-out", str(key_der)],
    check=True, capture_output=True, text=True,
)

scripts/opc_utils.py:422-425:

python
elif cmd == "cert":
    cn = sys.argv[2] if len(sys.argv) > 2 else "MyOPCApp"
    org = sys.argv[3] if len(sys.argv) > 3 else "MyCompany"
    generate_self_signed_cert(output_dir="./certs", common_name=cn, org=org)

Technical Analysis

The command-line common_name value is embedded directly into four output paths without rejecting directory separators, traversal components, absolute paths, or other unsafe filename characters. A value containing traversal ...[truncated 2132 chars]

Remediation
View remediation

Remediation Suggestions

  1. Separate the certificate subject common name from the filesystem basename. Generate a safe internal filename rather than using subject data as a path component.
  2. If a user-selected basename is required, enforce a strict allowlist such as ASCII letters, digits, periods, underscores, and hyphens.
  3. Explicitly reject path separators, traversal components, absolute paths, empty values, and platform-specific reserved names.
  4. Resolve the output directory and each candidate destination with Path.resolve(), then verify that every destination remains beneath the resolved output directory.
  5. Refuse to overwrite existing files unless the user provides a deliberate overwrite option.
  6. Reject symbolic links and create files atomically using exclusive creation semantics.
  7. Apply restrictive private-key permissions, such as owner read/write access only.
  8. Validate org, country, days, and subject fields independently before passing them to OpenSSL.
  9. Add tests covering traversal strings, absolute paths, symbolic links, pre-existing files, and unusual platform-specific filenames.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The C# example explicitly sets AutoAcceptUntrustedCertificates = true, unconditionally accepts certificates in the validation callback, and selects the endpoint with useSecurity: false. This disables core OPC UA authentication and transport protections, making it easy for a malicious or spoofed endpoint to impersonate a server and intercept or manipulate industrial data flows.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · references/opc-ua-troubleshooting.md (reported line 44)May include surrounding context.

3. 防火墙检查

Windows

netsh advfirewall firewall show rule name=all | findstr 4840

Linux

iptables -L -n | grep 4840

text

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger list contains very broad terms such as '错误', '失败', '安全', '工具', and '概念', which can match many unrelated user requests and cause this skill to activate outside its intended OPC scope. Over-broad activation increases the chance of misrouting user queries, accidental tool usage, or the model providing authoritative OPC-specific guidance in contexts where it is not appropriate.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Mandating '中文优先' without offering a user language choice can override user intent and reduce clarity for users who ask in another language. In security or industrial troubleshooting contexts, forced language output may increase misunderstanding of safety-critical steps, configuration details, or error interpretation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide explicitly tells users to select OPC UA 'None' security mode to test connectivity, but does not warn that this disables authentication protections, signing, and encryption. In an industrial control context, normalizing insecure initial setup can lead operators to leave systems exposed on production or routable networks, increasing the risk of eavesdropping, tampering, or unauthorized access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide tells users they may select SecurityPolicy None and trust a server certificate during first connection without clearly warning that this removes confidentiality/integrity protections and can normalize unsafe trust decisions. In an industrial protocol context, this can expose users to man-in-the-middle interception, spoofed servers, and unsafe habits being carried from lab setup into real environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This troubleshooting guide presents all instructions, headings, and operational guidance exclusively in Chinese, with no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-language audience.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/opc_utils.py (reported line 202)May include surrounding context.

python
try:
        # 生成私钥
        subprocess.run(
            ["openssl", "genrsa", "-out", str(key_pem), "2048"],
            check=True, capture_output=True, text=True,
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/opc_utils.py (reported line 208)May include surrounding context.

python
)

        # 生成自签名证书
        subprocess.run(
            ["openssl", "req", "-new", "-x509",
             "-key", str(key_pem),
             "-out", str(cert_pem),

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/opc_utils.py (reported line 218)May include surrounding context.

python
)

        # 导出 DER 格式
        subprocess.run(
            ["openssl", "x509", "-in", str(cert_pem),
             "-outform", "der", "-out", str(cert_der)],
            check=True, capture_output=True, text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/opc_utils.py (reported line 223)May include surrounding context.

python
"-outform", "der", "-out", str(cert_der)],
            check=True, capture_output=True, text=True,
        )
        subprocess.run(
            ["openssl", "rsa", "-in", str(key_pem),
             "-outform", "der", "-out", str(key_der)],
            check=True, capture_output=True, text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CLI browse command unconditionally enables show_values=True, causing address-space browsing to read and print live OPC UA variable values. In industrial/OT environments, those values can reveal sensitive operational telemetry, system state, identifiers, or process data to anyone with tool access, increasing information disclosure risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The entire skill content, including headings and instructional text, is presented only in Chinese. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file is entirely written in Chinese and does not indicate that the skill or reference is region-specific or that users may choose another language. Under the policy category, language constraints should either be optional for the user or clearly justified as locale-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

SQP-3 applies to all file types and includes language or locale policy violations. The file forces a specific language for all instructions without opt-in or documented regional justification, which can conflict with organizational language-choice policies.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file’s instructional content is entirely written in Chinese, including headings, explanatory text, and operational guidance, with no indication that the skill is intentionally region-specific or that alternative language support is available. Under the policy, a fixed language without user opt-in or documented justification is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

At L077 the comment says the first connection will automatically handle certificates, but the synchronous Python example only calls client.connect() without any visible trust-store or validation setup. This is an intent/documentation mismatch because the comment implies certificate handling behavior that is not actually implemented in the shown code.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
68% confidence
Finding

The code subscribes with await sub.subscribe_data_change(node) at L144, but later calls await sub.unsubscribe(node) at L150. The surrounding comments describe this as cleanup of the created monitored item, yet the code does not retain or use the subscription handle returned by the subscribe call, making the documented intent inconsistent with the implementation shown.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

该文件是完整的中文技术参考文档,但没有说明这是面向特定中文受众的区域性资料,也没有提供用户可选择的语言或多语言说明。根据语言/locale 政策,强制单一语言且无用户选择可能构成自然语言层面的政策问题。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

Natural-language strings in the module docstring, help text, and user-facing output are consistently Chinese-only. This effectively forces a language choice on users without opt-in or explanation, matching the locale-policy concern described by the rule.

Content

No source excerpt is available for this finding.