Back to skill

Security audit

cyber-events-log-abstract

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended for security-event reporting, but it embeds an XDR API key, disables TLS verification, and saves sensitive raw event data locally.

Review this skill carefully before installing. It should not be used as published unless the exposed XDR API key has been revoked and replaced with a user-provided secret, TLS verification is enabled, the XDR destination is configurable and authorized, and raw data retention is documented or disabled by default.

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

T09 · Insecure Skill Coding Practices

Error
Location
security_report.py:15
Finding
Hard-Coded XDR API Credential<![CDATA[ ## Vulnerability Details **File Location**: `security_report.py:15-20` **Vulnerability Type**: Hard-coded authentication secret **Risk Level**: High ```python API_URL = "https://10.50.86.28/xdr/openapi/v1.0/risk/listDetail" API_KEY = "7445a03b544484ff3ab552fd81d1f2b7" HEADERS = { "apikey": API_KEY, "accept": "*/*" } ``` ### Technical Analysis A reusable XDR API key is embedded directly in the source code and included in every request through the `apikey` HTTP header. Any person or process able to read the skill package can recover the credential without invoking the skill. Source-code permissions and package distribution controls are not suitable secret-management mechanisms. The credential may also remain recoverable from repository history, archived packages, logs, backups, and previously distributed copies after it is removed from the current source. ### Attack Path 1. An attacker obtains read access to the skill package, an archive, a repository clone, or a backup containing `security_report.py`. 2. The attacker reads the `API_URL` and `API_KEY` constants. 3. From a network location that can reach the private XDR endpoint, the attacker sends requests with the extracted key in the `apikey` header. 4. The attacker accesses any operations and data authorized to that key until the credential is revoked or rotated. ### Impact Assessment The exposed credential may permit unauthorized access to the internal XDR API and its security-event information. The exact privileges depend on the server-side permissions assigned to the key, which are not defined in the reviewed files. At minimum, the source demonstrates intended access to detailed XDR risk data. Exposure could therefore disclose internal IP addresses, affected assets, event classifications, threat severity, and operational security information. If the key has permissions beyond the demonstrated read operation, the impact could extend to other API capabilities available to that cred ...[truncated 13 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the exposed API key immediately; removing it from the current file is insufficient. 2. Review XDR access logs for suspicious use of the exposed credential. 3. Remove the secret from all repository history, package archives, build artifacts, logs, and backups where feasible. 4. Obtain the credential at runtime from a protected secret manager or a narrowly scoped environment variable. 5. Fail closed with a clear error when the credential is unavailable; do not provide a fallback key. 6. Assign a dedicated, read-only, least-privilege credential restricted to the required endpoint. 7. Restrict the credential by source network, workload identity, expiration time, and request scope where supported. 8. Add automated secret scanning to source-control and packaging workflows. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
security_report.py:45
Finding
TLS Certificate Verification Disabled for Authenticated XDR Requests<![CDATA[ ## Vulnerability Details **File Location**: `security_report.py:9-10` and `security_report.py:45-50` **Vulnerability Type**: Improper certificate validation **Risk Level**: High ```python # 禁用 SSL 警告(内网 IP) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) ``` ```python response = requests.get( API_URL, headers=HEADERS, params=params, verify=False, timeout=120 ) ``` ### Technical Analysis The request explicitly uses `verify=False`, disabling certificate-chain and hostname validation. The code also suppresses the warning that would normally identify this insecure configuration. Although the URL uses HTTPS, encryption without certificate validation does not reliably authenticate the XDR server. A network-positioned attacker can present an arbitrary certificate, terminate the connection, and impersonate the configured endpoint. Because the API key is sent in the request headers, successful interception can expose both the credential and the returned security-event information. The response is subsequently parsed as trusted JSON and used to create saved data and operational reports, so an impersonating server can also influence report contents. ### Attack Path 1. An attacker gains a position capable of intercepting or redirecting traffic to `10.50.86.28`, such as through a compromised gateway, local network access, route manipulation, or name/network configuration changes. 2. The attacker presents an arbitrary TLS certificate while impersonating the XDR endpoint. 3. The client accepts the certificate because `verify=False` disables authentication. 4. The attacker captures the `apikey` request header and query parameters. 5. The attacker may forward the request to the real service or return fabricated JSON. 6. Fabricated data is processed and may be saved as raw aggregate data and included in the generated security report. ### Impact Assessment A successful attack can disclose the hard-coded API key and sensi ...[truncated 422 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `verify=False` and rely on the default certificate validation behavior. 2. Remove global suppression of `InsecureRequestWarning`. 3. Configure the XDR service with a certificate whose subject alternative name matches the endpoint used by the client. 4. For an internal certificate authority, provide a protected CA bundle explicitly, for example: ```python response = requests.get( API_URL, headers=headers, params=params, verify="/protected/path/internal-ca.pem", timeout=120, ) ``` 5. Treat certificate-validation failures as fatal and do not retry over an unverified connection. 6. Rotate the API key because the disabled validation may already have exposed it. 7. Consider additional controls such as network allowlisting, short-lived credentials, and certificate pinning where operationally appropriate. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
security_report.py:103
Finding
Security Event Totals and Trends Use Aggregate Record Counts Instead of Event Counts<![CDATA[ ## Vulnerability Details **File Location**: `security_report.py:103-153` **Vulnerability Type**: Incorrect security-event aggregation and report integrity failure **Risk Level**: Medium The documented requirement states that `counts` or `eventCount` represents the total number of events and that aggregate record counts must not be used as event totals. The implementation nevertheless increments hourly values by one per record and returns the number of records as the total: ```python def build_trend_stats(trend_events): time_record_counter = defaultdict(int) severity_counter = Counter() object_counter = Counter() name_occurrence_counter = Counter() for e in trend_events: t = e.get("startTime") if not t: continue hour = t[:13] time_record_counter[hour] += 1 severity_counter[e.get("threatSeverity", "未知")] += 1 object_counter[e.get("focusObjectCN", "未知")] += 1 c = int(e.get("eventCount", 0) or 0) name_occurrence_counter[e.get("name", "未知")] += c if not time_record_counter: return {} sorted_times = sorted(time_record_counter.items()) first_count = sorted_times[0][1] last_count = sorted_times[-1][1] if last_count > first_count * 1.2: trend = "上升" elif last_count < first_count * 0.8: trend = "下降" else: trend = "波动" peak_time, peak_event_count = max(time_record_counter.items(), key=lambda x: x[1]) avg_event_count = int(sum(time_record_counter.values()) / len(time_record_counter)) return { "trend": trend, "timeBuckets": len(sorted_times), "peakTime": peak_time, "peakEventCount": peak_event_count, "avgEventCount": avg_event_count, "severityDistribution": severity_counter.most_common(3), "focusObjectDistribution": object_counter.most_common(), ...[truncated 2325 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse each aggregate count once using strict validation: ```python def get_event_count(event): value = event.get("eventCount", event.get("counts", 0)) count = int(value or 0) if count < 0: raise ValueError("Event count cannot be negative") return count ``` 2. Calculate the total as the sum of validated counts rather than `len(events)`. 3. Add the event count to each applicable hourly bucket: ```python time_event_counter[hour] += get_event_count(e) ``` 4. Derive peak, average, and trend values from event-volume buckets. 5. Clearly distinguish record-based metrics from event-volume metrics in field names and report labels. 6. Decide whether severity and object distributions should be record-based or event-volume-weighted, document that decision, and implement it consistently. 7. Add tests covering: - Multiple records with substantially different `counts` values. - Missing, null, string, negative, and malformed counts. - Cases where record-count trends and event-volume trends point in opposite directions. - Empty datasets and zero-count records. 8. Consider returning both `totalAggregateRecords` and `totalEvents` to eliminate ambiguity. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared purpose says the skill summarizes security events, but the behavior includes actively querying external or internal security platforms and, per the finding, authenticating with hardcoded credentials and accessing undeclared resources. That mismatch is dangerous because it conceals privileged data access behind an innocuous summary skill, reducing informed consent and increasing the chance of unauthorized collection or credential exposure.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill executes another Python script as a subprocess, which introduces code-execution capability beyond simple summary generation. In this context, that is more dangerous because a summarization skill should not need shell-mediated execution of auxiliary scripts, and compromise of the sibling script or execution path could lead to unintended code execution.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 执行命令
    import subprocess
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode != 0:
        raise Exception(f"执行安全报告脚本失败: {result.stderr}")
Confidence
96% confidence
Finding
This is a true tool-parameter abuse issue because user-controlled or runtime-derived data is interpolated into a shell command. Even though argparse enforces int for the CLI path, shell=True remains a fragile and unnecessary execution pattern that can become exploitable through future code changes, alternate call paths, or path/argument manipulation.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code globally disables TLS warnings and then connects with certificate verification disabled, which allows interception or spoofing of the XDR API connection. Because this code handles security-event data and API authentication, a man-in-the-middle attacker could tamper with results or capture credentials and sensitive telemetry.

Missing User Warnings

High
Confidence
99% confidence
Finding
A hardcoded API key is embedded directly in the source and used automatically for requests. If the file is shared, logged, committed, or reused by another system, the credential can be extracted and used to access the XDR API, potentially exposing sensitive security-event data or enabling further abuse depending on the API's permissions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares no explicit tool or permission scope, yet its instructions direct execution of local Python scripts, network access to XDR data sources, and report/output file generation. In an agent environment, this overbroad undeclared capability increases the risk of unintended shell execution, filesystem writes, and network access without policy visibility or user consent.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file describes the skill entirely in Chinese and the reporting template mandates a fixed Chinese output structure, but it does not indicate that language selection is optional or user-controlled. This can violate language/locale policy when users have not opted into Chinese-only responses.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The trigger phrases are broad enough to match common requests for security summaries, which can cause the skill to activate in contexts where the user did not intend this specific workflow. Because the skill may execute scripts and fetch security data, accidental invocation has greater consequences than a normal text-only skill.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file hard-codes Chinese-language docstrings, CLI descriptions, exceptions, headings, and status messages throughout the skill. That creates a language-policy issue because the skill mandates a specific language for interaction and output without any user opt-in, locale selection, or stated region-specific justification.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 执行命令
    import subprocess
    result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
    
    if result.returncode != 0:
        raise Exception(f"执行安全报告脚本失败: {result.stderr}")
Confidence
95% confidence
Finding
The code builds a shell command string and executes it with shell=True, even though part of the command includes a runtime parameter (days). This creates command-injection risk if the parameter validation is ever weakened, bypassed, or influenced indirectly, and it is unnecessary because the script path and arguments can be passed safely as an argument list.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill claims to generate concise summaries, but it also writes raw security event data to persistent local storage. Raw security logs often contain sensitive operational details, internal IPs, incident metadata, and potentially regulated data, so this expands the data exposure surface beyond the stated function.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill is described as a summarization/reporting utility, but it also initiates direct remote collection from an internal XDR endpoint. This expands its privileges and data-access scope beyond passive summarization, increasing the risk of unauthorized data retrieval, unexpected network access, and misuse in environments where users may assume only local processing occurs.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill performs an external network request that transmits security-event query parameters and retrieves sensitive event data without any explicit user-facing disclosure. In the context of a summarization skill, this is riskier because users may reasonably expect analysis of supplied data rather than silent remote collection from an internal security platform.

Unsafe Defaults

Medium
Category
Tool Misuse
Content
API_URL,
        headers=HEADERS,
        params=params,
        verify=False,
        timeout=120
    )
    response.raise_for_status()
Confidence
99% confidence
Finding
Using verify=False disables server certificate validation for this specific HTTPS request, making the connection vulnerable to man-in-the-middle attacks. Since the request includes an API key and accesses security telemetry, an attacker on the network path could intercept credentials, observe queries, or alter returned event data.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The manifest description states the skill is specifically for generating security incident summary reports in Chinese, using Chinese-only phrasing without indicating user opt-in or alternative language support. This creates a natural-language locale policy concern because it appears to enforce a specific language by default rather than offering a choice or documenting a region-specific justification.

Description-Behavior Mismatch

Low
Confidence
85% confidence
Finding
The stated purpose is to generate a concise abstract report from security events, which does not inherently require writing artifacts to the user's filesystem. Persisting the report as a file is an additional operational behavior beyond the manifest's narrowly described summarization scope.

Static analysis

No suspicious patterns detected.