Back to skill

Security audit

Gitlab CI Linter

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local GitLab CI linter that reads user-selected YAML files and reports issues, with no evidence of hidden execution, persistence, data exfiltration, or destructive behavior.

Installers should treat this as a local linting helper, not a definitive GitLab security authority. Use it on intended project paths, avoid pointing it at broad private directories unnecessarily, and verify important pipeline security decisions with GitLab's own CI linting or a full YAML parser-aware review.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gitlab_ci_linter.py:125
Finding
Unsupported YAML Constructs Are Silently Omitted, Causing Security Audit Bypass<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gitlab_ci_linter.py:125-141` and `scripts/gitlab_ci_linter.py:218-220` **Vulnerability Type**: Incomplete and fail-open parsing of security-sensitive input **Risk Level**: Medium ### Vulnerable Code ```python def _parse_mapping(self, expected_indent): result = {} while self.pos < len(self.lines): line = self.lines[self.pos] if not line.strip() or line.strip().startswith('#'): self.pos += 1 continue indent = self._current_indent(line) if indent < expected_indent: break if indent > expected_indent: self.pos += 1 continue stripped = self._strip_comment(line).strip() if stripped.startswith('- '): break # list context if ':' not in stripped: self.pos += 1 continue ``` The parser is invoked without checking whether it consumed and understood all security-relevant input: ```python def parse_yaml(text): parser = YAMLParser(text) return parser.parse() ``` ### Technical Analysis The project uses a custom, partial YAML parser for GitLab CI configuration. In `_parse_mapping`, lines with unexpected indentation or unsupported structure are silently skipped rather than causing a parsing error. The parser also does not implement important YAML features commonly accepted in GitLab CI, including anchors, aliases, merge keys, and tags. The `parse_yaml` wrapper returns the resulting partial mapping without verifying that every meaningful token or line was consumed. Security rules subsequently operate on this incomplete representation and can therefore reach incorrect conclusions. A concrete bypass can use a YAML merge key to inherit a security-sensitive property: ```yaml .security-defaults: &security-defaults allow_failure: true security_scan: <<: *security-defaults script: - run-security-scan ``` GitLab's YAML processing ca ...[truncated 1899 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the custom parser with a maintained YAML parser that safely supports the YAML constructs accepted by GitLab CI. 2. Use safe loading functionality and explicitly reject application-specific or executable object tags. 3. Resolve or deliberately reject anchors, aliases, and merge keys before running security rules. 4. Configure duplicate-key detection so duplicated jobs or properties cannot be silently overwritten. 5. Fail closed when unsupported syntax, unexpected indentation, malformed mappings, or unconsumed input is encountered. 6. Report parsing limitations as errors rather than continuing with a partial document. 7. Validate the normalized configuration against GitLab CI's schema or, where available, the official GitLab CI lint API. 8. Ensure the `security` command also reports parser and structural errors instead of running security checks against an uncertain model. 9. Add regression tests covering: - Anchors and aliases - Merge keys - Explicit YAML tags - Duplicate mapping keys - Nested mappings and sequences - Block scalars - Unexpected indentation - Malformed and partially parseable documents - Security properties inherited through YAML constructs 10. Clearly distinguish a successful complete audit from an incomplete or unsupported parse in every output format and return a nonzero exit status for the latter. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The manifest description says the skill triggers on phrases like "check pipeline", "validate CI", and "pipeline issues", which are broad enough to match many general CI/CD support requests. The description does not provide exclusion conditions or negative examples to clarify when the skill should not activate, increasing the risk of unintended invocation.

Missing User Warnings

Low
Confidence
81% confidence
Finding
This code recursively discovers YAML files under a user-supplied path and reads each file's contents, which is a file-access operation covered by the warning requirement for code files. While the script's high-level docstring says it lints pipeline files, there is no user-facing prompt, logging, or inline warning near the recursive scan/read behavior to disclose that an entire directory tree may be traversed and read.

Static analysis

No suspicious patterns detected.