T08 · Insecure Dependencies
- Location
scripts/emoji.mjs:55- Finding
Mutable and Unverified Remote Emoji Assets
- Content
View full analysis
{ const doFetch = (url, redirects = 0) => { if (redirects > 5) return reject(new Error('Too many redirects')); https.get(url, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { return doFetch(res.headers.location, redirects + 1); } if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`)); let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(data)); }).on('error', reject); }; doFetch(url); }); } /** * Get Twemoji SVG content for an emoji (with local caching) */ export async function getEmojiSvg(emoji) { const cp = emojiToCodepoint(emoji); // Check cache first if (!existsSync(CACHE_DIR)) mkdirSync(CACHE_DIR, { recursive: true }); const cachePath = join(CACHE_DIR, `${cp}.svg`); if (existsSync(cachePath)) { return readFileSync(cachePath, 'utf8'); } // Fetch from Twemoji CDN const url = `https://cdn.jsdelivr.net/gh/twitter/twemoji@latest/assets/svg/${cp}.svg`; try { const svg = await fetchUrl(url); writeFileSync(cachePath, svg); return svg; } catch (e) { // Fallback: return null (will render as text) return null; } } ``` ### Technical Analysis The emoji renderer downloads SVG files from a third-party CDN using the mutable `twemoji@latest` reference. Consequently, the effective asset content can change after the Skill has been reviewed or installed. The download process has the following weaknesses: - The Twemoji dependency is not pinned to an immutable version or commit. - Downloaded S ...[truncated 2367 chars]- Remediation
View remediation
