T09 · Insecure Skill Coding Practices
- Location
scripts/multi_hop_query_builder.py:116- Finding
Graph Query Injection Through Unvalidated Structural Parameters
- Content
View full analysis
(target{target_part}) RETURN DISTINCT target LIMIT {limit}""" ``` ```python path = f"ex:{relationship_type}" * num_hops query = f"""PREFIX ex: SELECT ?target WHERE {{ ex:{start_id_value} {path} ?target . }} LIMIT {limit}""" ``` ```python target_part = f":{target_label}" if target_label else "" query = f"""MATCH (start:{start_label})-[:{relationship_type}*{min_hops}..{max_hops}]->(target{target_part}) RETURN DISTINCT target LIMIT {limit}""" ``` ```python query = f"""PREFIX ex: SELECT ?target WHERE {{ ?start a ex:{start_label} ; ex:{relationship_type}+ ?target . }} LIMIT {limit}""" ``` ### Technical Analysis Query parameters can normally protect data values, but graph labels, relationship types, property names, SPARQL resource names, and query-language clauses generally cannot be safely treated as ordinary value parameters. These structural components require strict validation against the application schema. The following arguments are embedded directly into query syntax: - `start_ ...[truncated 2588 chars]- Remediation
View remediation
str: if not isinstance(value, str) or not IDENTIFIER.fullmatch(value): raise ValueError("Invalid graph identifier") return value ``` 2. Prefer explicit allowlists derived from the known graph schema: ```python ALLOWED_LABELS = {"Person", "Company", "Product"} ALLOWED_RELATIONSHIPS = {"FOLLOWS", "SUPPLIES", "PURCHASED"} ALLOWED_PROPERTIES = {"id", "name", "username"} ``` 3. Enforce runtime integer validation for all traversal and limit parameters. Reject booleans, negative values, zero where inappropriate, and oversized values: ```python def validate_positive_int(value, *, minimum=1, maximum=100): if isinstance(value, bool) or not isinstance(value, int): raise TypeError("Expected an integer") if not minimum <= value <= maximum: raise ValueError("Integer is outside the permitted range") return value ``` 4. Apply the safe-depth restriction consistently to fixed-depth, variable-depth, and path-discovery methods. 5. Parameterize every data value supported by the target database driver. Do not confuse value parameterization with identifier safety. 6. If the database supports identifier quoting, use the official driver or query-builder mechanism only after validation. Quoting alone should not replace schema allowlisting. 7. Treat generated statements as untrusted until validated. Document that callers must not directly execute queries created from arbitrary external input. 8. Add tests covering quotes, backticks, braces, parentheses, semicolons, comments, whitespace, newlines, clause keywords, booleans, negative depths, very large depths, and malformed limits. ]]>
