T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/filter_message.py:201
- Finding
- YAML Configuration Failure Silently Falls Back to Weaker Defaults<![CDATA[ ## Vulnerability Details **File Location**: `scripts/filter_message.py:201-217`; related dependency claim at `SKILL.md:19` **Vulnerability Type**: Fail-open security configuration caused by an undeclared dependency **Risk Level**: Medium ### Vulnerable Code ```python raw = p.read_text() ext = p.suffix.lower() try: if ext in (".yaml", ".yml"): try: import yaml loaded = yaml.safe_load(raw) except ImportError: # Fallback: minimal YAML parser not available; try json print("[filter_message] WARNING: pyyaml not installed, falling back to json parser", file=sys.stderr) loaded = json.loads(raw) else: loaded = json.loads(raw) cfg.update(loaded) except Exception as e: print(f"[filter_message] WARNING: failed to parse config ({e}), using defaults", file=sys.stderr) return cfg ``` The installation documentation makes the following conflicting claim: ```markdown 2. Navigate to the directory. The skill is dependency-free, relying only on the Python standard library. ``` ### Technical Analysis The documented YAML configuration format requires the third-party PyYAML module, despite the Skill claiming to use only the Python standard library. If PyYAML is unavailable, the implementation attempts to parse the YAML document as JSON. Ordinary YAML is generally not valid JSON, so this operation raises an exception. The outer exception handler only prints a warning and continues with `DEFAULT_CONFIG`. This is a fail-open design: an explicitly selected security policy can be discarded while message processing and transmission continue. Discarded settings can include: - Custom patterns for organization-specific credentials. - Overrides that change sensitive patterns from `mask` or `warn` to `block`. - Required detection logging. - Reduced prefix or suffix disclosure settings. - Other filtering controls expected by the operator. The warning is written to stderr and d ...[truncated 1393 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Make configuration failures fail closed: - If an explicitly selected configuration cannot be read or parsed, terminate with exit code 2. - Do not process or emit the outgoing message under fallback defaults. 2. Resolve the dependency contradiction: - Declare and pin PyYAML as a required dependency, or - Remove YAML support and document JSON as the only supported format, or - Implement a safe parser that actually uses only declared dependencies. 3. Validate the parsed root value before calling `cfg.update`: - Require a mapping/object. - Reject null, arrays, strings, and other invalid root types. 4. Validate all security-relevant fields against a strict schema, including actions, pattern definitions, capture groups, and numeric masking settings. 5. Clearly distinguish optional default-file behavior from explicit configuration: - An absent default file may reasonably use defaults. - A supplied but invalid `--config` file must be treated as a fatal policy error. 6. Add automated tests covering missing PyYAML, malformed YAML, malformed JSON, invalid root types, and custom rules that must not be silently discarded. ]]>
