T08 · Insecure Dependencies
- Location
scripts/setup.sh:18- Finding
External Font Assets Are Consumed Without Integrity Verification
- Content
View full analysis
Vulnerability Details
File Location:
scripts/setup.sh:18-31, 38-49
Vulnerability Type: Unverified third-party asset downloads
Risk Level: MediumVulnerable Code
bash # 3. Download Virgil font (Excalidraw's handwritten font) if [ ! -f "$FONT_DIR/Virgil.ttf" ]; then echo "→ Downloading Virgil font..." curl -sL "https://cdn.jsdelivr.net/npm/@excalidraw/excalidraw@0.17.6/dist/excalidraw-assets/Virgil.woff2" \ -o "$FONT_DIR/Virgil.woff2" # Convert woff2 → ttf using fonttools (needed for resvg) if command -v python3 &>/dev/null && python3 -c "import fontTools" 2>/dev/null; then python3 -c " from fontTools.ttLib import TTFont font = TTFont('$FONT_DIR/Virgil.woff2') font.flavor = None font.save('$FONT_DIR/Virgil.ttf') print(' Converted Virgil.woff2 → Virgil.ttf') "bash # 4. Download Cascadia Code (for code font) if [ ! -f "$FONT_DIR/CascadiaCode.ttf" ]; then echo "→ Downloading Cascadia Code font..." CASCADIA_VERSION="2404.23" curl -sL "https://github.com/microsoft/cascadia-code/releases/download/v${CASCADIA_VERSION}/CascadiaCode-${CASCADIA_VERSION}.zip" \ -o /tmp/cascadia.zip cd /tmp unzip -qo cascadia.zip -d cascadia_extract 2>/dev/null || true find cascadia_extract -name "CascadiaCode*.woff2" -not -path "*/static/*" | head -1 | xargs -I{} cp {} "$FONT_DIR/CascadiaCode.woff2" 2>/dev/null || true find cascadia_extract -name "CascadiaCode-Regular.ttf" | head -1 | xargs -I{} cp {} "$FONT_DIR/CascadiaCode.ttf" 2>/dev/null || trueTechnical Analysis
The setup script downloads font assets over HTTPS but does not verify an expected cryptographic digest or signature before parsing, extracting, installing, and later loading them into the renderer.
The URLs use versioned assets from jsDelivr and the official Microsoft GitHub repository. The static pre-scan characterization of the Cascadia download as an executable from a personal or pastebin site is therefore inaccurate: the downloaded object is a ...[truncated 2229 chars]
- Remediation
View remediation
Remediation Suggestions
- Pin a trusted SHA-256 digest for each exact downloaded artifact and verify it before parsing or extraction:
bash curl --fail --show-error --location "$URL" --output "$FILE" printf '%s %s\n' "$EXPECTED_SHA256" "$FILE" | sha256sum --check -- Abort immediately when verification, extraction, conversion, or copying fails. Remove
|| trueand avoid suppressing relevant error output. - Prefer vendoring the reviewed font files in the Skill package when licensing permits. This removes setup-time network access and makes the audited artifact match the executed artifact.
- If upstream signatures are available, verify them against a pinned, trusted signing key in addition to hashes.
- Validate archive contents before extraction and accept only the exact expected font paths and file types.
- Run setup as an unprivileged user and document that it must not be run with
sudoor as root. - Consider
npm ci --ignore-scriptsinstead ofnpm installwhen compatible with required dependencies, so installation exactly follows the lockfile and avoids unnecessary lifecycle-script execution.
