Back to skill

Security audit

Config Manager - 配置管理器

Security checks for vulnerabilities and agentic risk

Overview

This is a small C configuration-management helper that does only disclosed, user-directed config loading and saving, though its parser and serializer need hardening before security-sensitive use.

Reasonable to install for review or experimentation. Before using this in production or security-sensitive software, harden empty-value parsing, integer range checks, key/value escaping, and path handling; do not load attacker-controlled configuration files or save untrusted strings without validation.

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

Warning
Location
code.c:186
Finding
Undefined Behavior When Parsing an Empty Configuration Value<![CDATA[ ## Vulnerability Details **File Location**: `code.c`, lines 186–193 **Vulnerability Type**: Out-of-bounds pointer formation and undefined behavior **Risk Level**: Medium ### Vulnerable Code ```c char* eq = strchr(line, '='); if (eq) { *eq = '\0'; char* key = line; char* value = eq + 1; // Remove whitespace while (*value == ' ' || *value == '\t') value++; char* end = value + strlen(value) - 1; while (end > value && (*end == '\n' || *end == '\r' || *end == ' ')) *end-- = '\0'; ``` ### Technical Analysis When a configuration entry has an empty value and no trailing newline, such as `key=` at the end of a file, `value` points to an empty string and `strlen(value)` returns zero. The expression below consequently attempts to form a pointer one byte before the beginning of the `value` object: ```c char* end = value + strlen(value) - 1; ``` Forming this out-of-bounds pointer is undefined behavior under the C memory model, even if the following loop condition normally prevents it from being dereferenced. Compiler optimizations, runtime instrumentation, or platform-specific behavior may therefore produce unpredictable results. The same condition can occur after leading spaces or tabs are skipped if no other characters remain and the line has no newline terminator. ### Attack Path 1. An attacker gains control over a configuration file accepted by an application using this library. 2. The attacker places an empty assignment such as `key=` as the final line without a newline. 3. The application calls `config_load_file()` on that file. 4. The parser calculates `value + 0 - 1`, forming an invalid pointer. 5. The application encounters undefined, compiler-dependent behavior and may terminate, particularly under memory-safety instrumentation or hardened runtime environments. ### Impact Assessment The direct impact is availability loss or unpredictable configuration parsing in the process loading the malicious file. The flaw ...[truncated 275 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Track the string length before calculating the final character position, and only index the string when the length is nonzero. For example: ```c while (*value == ' ' || *value == '\t') { value++; } size_t value_len = strlen(value); while (value_len > 0) { char last = value[value_len - 1]; if (last != '\n' && last != '\r' && last != ' ' && last != '\t') { break; } value[--value_len] = '\0'; } ``` Additionally: - Define and test the intended behavior for empty configuration values. - Add regression tests for `key=`, `key= `, empty final lines, and files both with and without trailing newlines. - Compile tests with AddressSanitizer and UndefinedBehaviorSanitizer. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
code.c:199
Finding
Unchecked Integer Conversion and Unsafe Narrowing<![CDATA[ ## Vulnerability Details **File Location**: `code.c`, lines 199–204 **Vulnerability Type**: Integer range validation failure **Risk Level**: Medium ### Vulnerable Code ```c // Try parsing as an integer char* endptr; long val = strtol(value, &endptr, 10); if (*endptr == '\0') { config_add_int(cm, key, (int)val); } else { config_add_string(cm, key, value); } ``` ### Technical Analysis The parser uses `strtol()` and then narrows its `long` result to `int` without validating the conversion range. It does not: - Set `errno` to zero before calling `strtol()`. - Check whether `strtol()` reports `ERANGE`. - Check whether the parsed value is between `INT_MIN` and `INT_MAX`. - Verify that at least one digit was consumed by checking `endptr != value`. If a syntactically numeric value exceeds the representable range of `long`, `strtol()` returns a saturated value and sets `errno` to `ERANGE`, but the code still accepts and narrows it. If the value fits in `long` but not in `int`, the cast produces an implementation-defined result. This can silently transform attacker-supplied configuration limits into unintended negative, truncated, or otherwise incorrect values. ### Attack Path 1. An attacker controls or modifies a configuration file loaded by the host application. 2. The attacker supplies an oversized numeric setting, such as a value greater than `INT_MAX`, for a security-relevant limit. 3. `strtol()` parses the text, but the loader does not check overflow or the target `int` range. 4. The result is cast to `int`, potentially changing its sign or numeric value. 5. The consuming application retrieves the corrupted value through `config_get_int()`. 6. If that application uses the value for a timeout, resource limit, access threshold, pool size, retry count, or similar control, its intended policy may be bypassed or destabilized. ### Impact Assessment The library itself does not enforce a security policy, so the final effect depends on how the ...[truncated 406 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Perform complete conversion validation before storing the value: ```c #include <errno.h> #include <limits.h> errno = 0; char* endptr = NULL; long val = strtol(value, &endptr, 10); if (endptr != value && *endptr == '\0' && errno != ERANGE && val >= INT_MIN && val <= INT_MAX) { if (!config_add_int(cm, key, (int)val)) { /* Handle insertion failure. */ } } else { /* Reject the invalid integer or treat it according to an explicit policy. */ } ``` Further hardening should include: - Rejecting out-of-range values rather than silently treating them as strings when a key is expected to be numeric. - Supporting per-key minimum and maximum constraints. - Propagating parse errors to the caller instead of returning success for partially invalid files. - Testing `INT_MIN`, `INT_MAX`, adjacent out-of-range values, `LONG_MIN`, `LONG_MAX`, and extremely long numeric strings. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
code.c:233
Finding
Configuration Injection Through Unescaped Serialization<![CDATA[ ## Vulnerability Details **File Location**: `code.c`, lines 233–237 **Vulnerability Type**: Configuration-file injection **Risk Level**: Medium ### Vulnerable Code ```c fprintf(f, "%s = ", item->key); switch (item->type) { case CONFIG_STRING: fprintf(f, "%s\n", item->value.str_value); break; ``` ### Technical Analysis Keys and string values are written directly to a line-oriented `key=value` file without escaping or rejecting structural characters. In particular, newline and carriage-return characters in a key or value can create additional configuration records. For example, a string value equivalent to: ```text ordinary admin=true ``` is serialized as multiple lines. When the generated file is later loaded, `admin=true` is interpreted as an independent Boolean configuration entry. Keys containing line breaks or `=` characters can produce similar structural ambiguity. The issue is not a format-string vulnerability because the untrusted data is passed through `%s`. It is a data-format injection vulnerability caused by the absence of encoding and validation at the serialization boundary. ### Attack Path 1. An attacker supplies a key or string value to an application that exposes `config_add_string()` to untrusted input. 2. The supplied value contains a newline followed by an attacker-selected assignment, such as `\nadmin=true`. 3. The application calls `config_save_file()`. 4. The serializer writes the embedded newline literally, creating an additional configuration line. 5. The generated file is subsequently loaded through `config_load_file()` or consumed by another compatible parser. 6. The injected assignment is interpreted as a distinct configuration setting. 7. Depending on insertion order and key selection, the injected setting may add or replace a security-relevant option. ### Impact Assessment An attacker may manipulate the contents and meaning of saved configuration files, introduce unauthorized settings, or ov ...[truncated 542 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Adopt an unambiguous serialization strategy. Suitable options include: 1. Reject line breaks, carriage returns, NUL bytes, and unsupported delimiters in keys. 2. Escape structural characters in string values and implement corresponding unescaping in the loader. 3. Replace the ad hoc format with a well-specified serialization format and a maintained parser. At minimum, validate data before storing or saving it: ```c static bool valid_key(const char* key) { if (!key || *key == '\0') return false; return strpbrk(key, "\r\n=") == NULL; } static bool valid_single_line_value(const char* value) { if (!value) return false; return strpbrk(value, "\r\n") == NULL; } ``` Also: - Return an error if any key or value cannot be represented safely. - Write to a temporary file and atomically replace the destination only after every item has been validated and all writes have succeeded. - Add round-trip tests proving that saving and loading cannot create extra keys. - Test newline, carriage-return, delimiter, comment-marker, empty-string, and whitespace edge cases. ]]>
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
SQP-3 applies to all file types and covers language or locale policy violations. The document forces a single language for all instructions and descriptions, with no user opt-in, alternative language, or stated region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This code's natural-language comments, title, and demo output are presented only in Chinese, with no indication that the skill is region-specific or that users can opt into another language. The policy requires avoiding forced language or locale constraints unless they are optional or clearly justified.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This is a markdown file, so SQP-2 applies to omissions in user-facing warnings. The changelog explicitly states the skill supports configuration file loading/saving, but the document does not warn users that it may read from or write to configuration files, which could affect user data or project settings.

Static analysis

No suspicious patterns detected.