T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/notifier.py:82
- Finding
- Unescaped Dynamic Values in Telegram HTML Notifications<![CDATA[ ## Vulnerability Details **File Location**: `scripts/notifier.py`, lines 82-126 **Vulnerability Type**: Telegram HTML injection and notification-content manipulation **Risk Level**: Medium ### Vulnerable Code ```python message = f""" {emoji} <b>价格警报</b> <b>代币:</b> {token.upper()} <b>当前价格:</b> ${current_price:,.2f} <b>目标价格:</b> ${target_price:,.2f} <b>条件:</b> {direction} <b>时间:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} #SolanaMonitor #PriceAlert """ return self.send_message(message) def send_whale_alert(self, signature: str, amount: float, token: str, from_addr: str, to_addr: str) -> bool: message = f""" 🐋 <b>巨鲸转账警报</b> <b>金额:</b> {amount:,.2f} {token.upper()} <b>来源:</b> <code>{from_addr[:16]}...{from_addr[-8:]}</code> <b>目标:</b> <code>{to_addr[:16]}...{to_addr[-8:]}</code> <b>交易:</b> <a href="https://solscan.io/tx/{signature}">查看</a> <b>时间:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} #SolanaMonitor #WhaleAlert """ return self.send_message(message) ``` The resulting messages are passed to `send_message()`, whose default parsing mode is HTML: ```python def send_message(self, message: str, parse_mode: str = 'HTML') -> bool: ``` ### Technical Analysis The notification functions interpolate `token`, `from_addr`, `to_addr`, and `signature` directly into content rendered by Telegram as HTML. These values are not HTML-escaped or validated before insertion. If an attacker can influence any of these fields through a future API integration, monitored data source, plugin, or direct invocation of `NotificationManager.send_alert()`, HTML metacharacters may alter the structure or presentation of the notification. The `signature` value is particularly sensitive because it is inserted into an HTML link attribute. Telegram restricts the HTML elements it supports, limiting the scope compared with browser-based HTML injection. Nevertheless, crafted values may create misleading formatting, alter links, produce de ...[truncated 1278 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Escape every dynamic text field before inserting it into Telegram HTML: ```python from html import escape safe_token = escape(token.upper(), quote=True) safe_from_addr = escape(from_addr, quote=True) safe_to_addr = escape(to_addr, quote=True) ``` 2. Strictly validate Solana transaction signatures and wallet addresses before including them in messages. Reject values containing characters outside the expected Base58 alphabet and enforce appropriate length limits. 3. Construct the Solscan link only after validation: ```python import re BASE58_RE = re.compile(r"^[1-9A-HJ-NP-Za-km-z]+$") if not BASE58_RE.fullmatch(signature): raise ValueError("Invalid Solana transaction signature") safe_signature = escape(signature, quote=True) tx_url = f"https://solscan.io/tx/{safe_signature}" ``` 4. Consider using plain-text notifications when rich formatting is unnecessary. 5. Add tests using values containing `<`, `>`, `&`, quotation marks, closing tags, and fake link markup. Confirm that the resulting message displays these values literally and cannot introduce new Telegram entities. 6. Treat all alert fields as untrusted at the notification boundary, even when current callers normally obtain them from public blockchain or pricing services. ]]>
