Item #003 — copilot.microsoft.com (landing) — snapshot now

Source: full HTML (SPA shell)
Labels: #security #privacy #perf #seo #a11y

Verdict: Medium (mostly solid, a few easy wins)
It’s a modern module-bundled SPA with nonced inline scripts (good CSP hygiene) and a lean shell, but there are a handful of privacy, referrer/OG, and perf tune-ups you can apply without changing app logic.


Findings & fixes

High

  • Consent gating for telemetry & 3P beacons
    Several inline frameworks log to Bing endpoints and error/CLS pipelines (/fd/ls/lsp.aspx, directLog, navigator.sendBeacon). Make sure they respect user choice (region, consent).
    Fix: initialize logging only after consent and set a global flag to no-op before consent: // before any instrumentation is defined: window.__allowTelemetry__ = false; // wrap directLog / sendBeacon uses: function safeBeacon(url, body){ if (!window.__allowTelemetry__) return false; try { return navigator.sendBeacon?.(url, body) || false; } catch { return false; } }
  • Referrer Policy (privacy)
    You set origin-when-cross-origin. Prefer strict-origin-when-cross-origin to avoid sending path/query to same-scheme cross-origin. <meta name="referrer" content="strict-origin-when-cross-origin">

Medium

  • Open Graph image size
    og:image:width=600 / height=315 is small for high-DPI shares.
    Fix: serve a 1200×630 (or larger) asset and declare dimensions: <meta property="og:image" content="https://…/copilot-1200x630.jpg"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630">
  • Preconnect your static CDN
    Static bundles/fonts are on studiostaticassetsprod.azureedge.net. Add preconnect to reduce TLS/handshake latency: <link rel="preconnect" href="https://studiostaticassetsprod.azureedge.net" crossorigin> <link rel="dns-prefetch" href="//studiostaticassetsprod.azureedge.net">
  • Subresource Integrity (SRI)
    External scripts/styles load with crossorigin but no SRI. If bundle URLs are content-hashed and stable, add integrity: <link rel="stylesheet" href="…/index-abc123.css" integrity="sha384-…" crossorigin="anonymous"> <script type="module" src="…/vendor-abc123.js" integrity="sha384-…" crossorigin="anonymous"></script>
  • Noscript accessibility hint
    The shell is just <div id="app"></div>. Provide a minimal noscript message for assistive tech and non-JS environments: <noscript><p>Copilot requires JavaScript to run. Please enable JavaScript, or use the Copilot mobile app.</p></noscript>
  • Permissions/Feature Policy
    You likely don’t need broad device APIs on the landing shell. Set a conservative policy at the document level (headers ideally, meta fallback in dev): <!-- Prefer server header: Permissions-Policy --> <meta http-equiv="Permissions-Policy" content="geolocation=(), microphone=(), camera=(), usb=(), payment=()">

Low

  • Icons & favicons
    You declare both .ico and .svg favicons. That’s fine; ensure the .svg includes a fallback color for dark mode. Consider mask-icon for Safari pinned tabs.
  • Font loading
    You preload the variable font—good. Ensure font-display: swap|optional is set in the CSS to mitigate FOIT (not visible from the HTML).
  • SEO / SPA routing
    Since this is an SPA, confirm your client router updates <title>/og:*/canonical on route changes (or serve pre-rendered HTML per route). The shell meta is good for the root.
  • CSP & security headers(server)
    You use nonces on inline scripts—great signal that CSP is enforced. Also ensure headers for:
    • Content-Security-Policy with script-src 'self' 'nonce-…' https://studiostaticassetsprod.azureedge.net …
    • Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    • X-Content-Type-Options: nosniff
    • Cross-Origin-Opener-Policy: same-origin
    • Cross-Origin-Embedder-Policy: require-corp (if you ever do streaming/wasm and can isolate)

Quick wins

  • Switch referrer policy → strict-origin-when-cross-origin.
  • Add preconnect to azureedge.net.
  • Upgrade OG image to 1200×630.
  • Gate telemetry/logging behind consent flag.
  • Provide noscript message.
  • Add SRI to static bundles (if feasible).
  • Confirm CSP + security headers on the edge.

Drop the next URL when you’re ready—I’ll keep stamping these with concise diffs and priority.