T09 · Insecure Skill Coding Practices
- Location
- generator.py:119
- Finding
- Plaintext arXiv Metadata Retrieval Enables Generated Markdown Content Injection<![CDATA[ ## Vulnerability Details **File Location**: `generator.py:119-123`, `generator.py:144-145`, and `generator.py:207-210` **Vulnerability Type**: Unauthenticated transport and unsafe Markdown generation **Risk Level**: Medium ### Vulnerable Code The arXiv feed is retrieved over plaintext HTTP: ```python url = ( f'http://export.arxiv.org/api/query?' f'search_query=cat:cs.CV&sortBy=submittedDate' f'&sortOrder=descending&max_results={max_results}' ) ``` The externally supplied title is accepted with no Markdown-specific validation or escaping: ```python title = entry.find('atom:title', ns).text.strip().replace('\n', ' ')[:120] summary = entry.find('atom:summary', ns).text.strip().replace('\n', ' ')[:600].lower() ``` The title is subsequently inserted directly into a Markdown link label: ```python lines.append( f'- {src_tag} [{p["title"]}]({p["url"]})' f'{up_str}\n' ) ``` ### Technical Analysis The arXiv API request uses unencrypted HTTP. Consequently, its XML response has neither transport confidentiality nor server authenticity. An attacker capable of intercepting the network connection—including a compromised network gateway, hostile Wi-Fi access point, or maliciously configured proxy—can modify paper metadata before it reaches the application. The application parses the modified title and places it directly inside a Markdown link label. Truncating the title to 120 characters and replacing newline characters does not neutralize Markdown metacharacters such as `]`, `[`, `(`, and `)`. A forged title can therefore terminate the intended link label and introduce additional rendered Markdown content, including a misleading attacker-controlled link. The generated URL itself remains constructed from the parsed paper identifier and an expected host, but the unescaped title permits visual content and link spoofing within the report. This issue does not provide a direct local command-execution primitive. ### Attack Path 1. A user or ...[truncated 1239 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Retrieve the arXiv feed exclusively through HTTPS: ```python url = ( f'https://export.arxiv.org/api/query?' f'search_query=cat:cs.CV&sortBy=submittedDate' f'&sortOrder=descending&max_results={max_results}' ) ``` 2. Escape all externally supplied text before placing it into Markdown. At minimum, neutralize backslashes, square brackets, parentheses, and control characters: ```python def escape_markdown_label(value): value = re.sub(r'[\x00-\x1f\x7f]', ' ', value) return ( value.replace('\\', '\\\\') .replace('[', '\\[') .replace(']', '\\]') .replace('(', '\\(') .replace(')', '\\)') ) ``` Apply this function to every remote title before formatting the Markdown output. 3. Continue constructing destination URLs from validated identifiers rather than accepting URLs from remote metadata. Validate paper identifiers against a strict pattern such as: ```python if not re.fullmatch(r'\d{4}\.\d{4,5}', pid): continue ``` 4. Restrict generated links to approved HTTPS hosts, such as `arxiv.org` and `huggingface.co`. 5. Add automated tests containing hostile titles with Markdown delimiters, control characters, and attempted nested links to verify that generated reports cannot alter the intended document structure. ]]>
