T09 · Insecure Skill Coding Practices
- Location
scripts/init_governance.py:133- Finding
Governance Root Escape Through Unsanitized Path Identifiers
- Content
View full analysis
list[Path]: """Resolve the policy chain from root to leaf based on context.""" chain = [] # Organization org = context.get('organization', 'default') org_path = root / 'organizations' / org if org_path.exists(): chain.append(org_path) # Team team = context.get('team') if team: team_path = root / 'teams' / team if team_path.exists(): chain.append(team_path) # Project project = context.get('project') if project: project_path = root / 'project ...[truncated 2596 chars]- Remediation
View remediation
str: if not isinstance(value, str) or not IDENTIFIER.fullmatch(value): raise ValueError("Invalid governance identifier") if value in {".", ".."}: raise ValueError("Invalid governance identifier") return value ``` 2. Canonicalize the expected base and candidate paths before filesystem access: ```python base = (Path(path) / "teams").expanduser().resolve() candidate = (base / validate_identifier(name)).resolve() if not candidate.is_relative_to(base): raise ValueError("Policy path escapes the governance root") ``` 3. Apply the same validation and containment check to all identifiers received through JSON context. 4. Consider symlink attacks. Check containment after resolution and avoid following attacker-controlled symlinks where the deployment threat model permits them. 5. Do not overwrite an existing policy by default. Use exclusive creation mode (`x`) or require an explicit `--force` option after verifying the destination. 6. Add tests covering absolute paths, `../` traversal, nested separators, symlink escapes, empty identifiers, and valid identifiers. ]]>
