T09 · Insecure Skill Coding Practices
- Location
scripts/sinks/_md.py:40- Finding
Arbitrary Local File Disclosure Through Markdown Image References
- Content
View full analysis
list: """Return ``[(alt, ref, Path)]`` for image refs that point at existing local files.""" base = Path(base_dir) if base_dir else None found = [] seen = set() for match in _IMAGE_RE.finditer(markdown): ref = match.group("ref") if is_remote(ref) or ref in seen: continue path = Path(ref) if not path.is_absolute() and base is not None: path = base / ref if path.is_file(): found.append((match.group("alt"), ref, path)) seen.add(ref) return found ``` `scripts/sinks/linear.py:33-60`: ```python def _data_uri(path: Path) -> str: mime = _MIME.get(path.suffix.lower(), "image/png") b64 = base64.b64encode(path.read_bytes()).decode("ascii") return f"data:{mime};base64,{b64}" @register class LinearSink(Sink): name = "linear" requires = ("LINEAR_API_KEY", "LINEAR_TEAM_ID") label = "Linear issue (GraphQL API)" def deliver(self, doc: ParsedDoc) -> SinkResult: key = self.env("LINEAR_API_KEY") team = self.env("LINEAR_TEAM_ID") headers = {"Authorization": key, "Content-Type": "application/json"} base_dir = Path(doc.markdown_path).parent if doc.markdown_path else None images = _md.find_local_images(doc.markdown, base_dir) mapping = {ref: _data_uri(path) for _alt, ref, path in images} body = _md.rewrite_images(doc.markdown, mapping) status, parsed = _http.request_json("POST", API, headers=headers, payload={ "query": _MUTATION, "variables": {"input": { "teamId": team, "title": doc ...[truncated 2250 chars]- Remediation
View remediation
/images/`. 5. Apply an allowlist of supported image extensions and verify file signatures rather than trusting the filename. 6. Reject symbolic links or confirm that their resolved targets remain under the authorized directory. 7. Add file-size limits before reading and Base64-encoding assets. 8. Require explicit confirmation before a sink embeds any local file. 9. Add regression tests for absolute paths, `../` traversal, symlinks, encoded traversal, and paths sharing only a lexical prefix with the allowed directory. ]]>
