Back to skill

Security audit

Knowledge Graph - Graphql Graph Mapping

Security checks for vulnerabilities and agentic risk

Overview

This skill is not malicious, but it needs review because its production-labeled mapper can generate unsafe database queries and lacks guardrails for sensitive or write-capable graph data.

Review this skill before installing in workflows connected to real databases. Use it only with authorized data sources, prefer read-only and least-privilege database accounts, do not expose the included mapper directly to untrusted GraphQL input, and require explicit approval plus parameterized backend APIs for any write-capable operation.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/graphql_mapper.py:349
Finding

Graph Query Injection Through Unparameterized Query Construction

Content
View full analysis
str: """Build WHERE clause from GraphQL where object.""" clauses = [] for key, value in where_obj.items(): if isinstance(value, dict): # Comparison operators for op, val in value.items(): if op == "eq": clauses.append(f"{key} = {val}") elif op == "gt": clauses.append(f"{key} > {val}") elif op == "lt": clauses.append(f"{key} < {val}") else: clauses.append(f"{key} = {value}") return " AND ".join(clauses) ``` ### Technical Analysis The mapper constructs executable graph query strings by directly interpolating GraphQL argument values into Cypher, Gremlin, and SPARQL syntax. No parameter binding, literal escaping, strict type validation, or backend-specific encoding is applied. The Cypher translator places an `id` inside a quoted property literal. An attacker-controlled value containing a quote can terminate that li ...[truncated 2072 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/graphql_mapper.py:101
Finding

Denial of Service Through Non-Terminating Parsing and Unbounded Nesting

Content
View full analysis
List[Dict[str, Any]]: """Parse GraphQL selection set.""" selections = [] self._skip_whitespace() if self._current_char() != '{': return selections self._skip_char('{') self._skip_whitespace() while self._current_char() != '}': field = self._parse_field() selections.append(field) self._skip_whitespace() self._skip_char('}') return selections ``` ```python def _parse_string(self) -> str: """Parse string value.""" self._skip_char('"') value = "" while self._current_char() != '"': if self._current_char() == '\\': self.current_pos += 1 value += self._current_char() self.current_pos += 1 self._skip_char('"') return value ``` ```python def _parse_list(self) -> List[Any]: """Parse list value.""" self._skip_char('[') values = [] while self._current_char() != ']': values.append(self._parse_value()) self._skip_char(']') return values def _parse_object(self) -> Dict[str, Any]: """Parse object value.""" self._skip_char('{') obj = {} while self._current_char() != '}': key = self._read_identifier() self._skip_whitespace() self._skip_char(':') self._skip_whitespace() obj[key] = self._parse_value() self._skip_whitespace() self._skip_char('}') return obj ``` ### Technical Analysis Parser loops use only a closing delimiter as their termination condition and do not explicitly reject end-of-input. They also do not verify that each iteration advances `current_pos`. For an unterminated selection set, `_current_char()` returns `None` at the end of the input. Because `None != '}'`, the ...[truncated 1759 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The corporate knowledge graph example demonstrates retrieval and return of employee emails and reporting relationships, which can affect privacy and organizational confidentiality. The markdown description presents this behavior as normal usage but does not warn that such data should be access-controlled and handled carefully in real deployments.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes mapping GraphQL queries and schemas to underlying graph database operations for accessing knowledge graph data, which reads as primarily translation/access-oriented behavior. This file additionally documents create/update relationship and node mutation patterns that perform writes to the graph, expanding behavior beyond simple access/query translation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring says the implementation translates GraphQL queries and maps results back to GraphQL response format, suggesting support for the nested GraphQL structures implied by the parsed selections. However, _map_results_recursive only looks at the first top-level result entry and copies direct fields without recursively traversing nested selections, so the documented behavior materially overstates what the code does.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

_parse_value advertises parsing variable values, but _parse_variable returns only the identifier name without the leading $. Later translation logic checks startswith("$") before resolving variables, so parsed variables are treated as plain strings instead of variable references, contradicting the documented parser behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

_process_selection_for_cypher is documented as processing a GraphQL selection for Cypher and computes nested relationship traversals via _process_nested_selections_cypher. However, the returned relationships string is never incorporated into node_pattern, so nested selections do not affect the generated Cypher despite the code comments and function purpose implying that they should.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill explicitly describes translating and executing GraphQL-derived queries against live graph databases, including support for mutations and execution contexts, but does not warn about the risks of reading sensitive production data or triggering data-modifying operations. In an agent setting, this omission can encourage unsafe use of the skill on connected databases without clear guardrails, increasing the chance of unintended data exposure or modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file includes example response payloads containing email fields and concrete email addresses, which are a form of personal/contact data. Under the markdown-file warning criterion, the document does not include any caution that examples involving user or employee data may implicate privacy considerations when applied to real datasets.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.