diff --git a/.circleci/config.yml b/.circleci/config.yml
index fc32431e9..a016f2ed0 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -16,7 +16,10 @@ jobs:
- dependency-cache-{{ checksum "package-lock.json" }}
- run:
name: Install dependencies & peer dependencies
- command: npm install
+ command: npm ci
+ - run:
+ name: Audit for high-severity vulnerabilities
+ command: npm audit --audit-level=high
- save_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
paths: node_modules
diff --git a/.github/workflows/npm-storybook-release.yml b/.github/workflows/npm-storybook-release.yml
index 7dc6de7dc..38f0cedb3 100644
--- a/.github/workflows/npm-storybook-release.yml
+++ b/.github/workflows/npm-storybook-release.yml
@@ -16,7 +16,8 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 20.13.1
- - run: npm install
+ - run: npm ci
+ - run: npm audit --audit-level=high
- run: npm run build
- run: npx semantic-release
env:
diff --git a/ai-docs/SECURITY.md b/ai-docs/SECURITY.md
index 2b09ba9fa..06452dbae 100644
--- a/ai-docs/SECURITY.md
+++ b/ai-docs/SECURITY.md
@@ -46,11 +46,11 @@ Evidence: `.gitignore` (`.env*`), `CONTRIBUTING.md`.
## Input Validation & Output Encoding Posture
-- Validate URLs with `isValidUrl` and explicit protocol allow-lists where used.
-- Markdown rendering in messaging uses `markdown-it` — hosts should sanitize untrusted content before display if sourcing external messages.
+- Validate URLs with `isValidUrl` and explicit protocol allow-lists where used. For `http:` and `https:` URLs, `isValidUrl` additionally rejects loopback hosts (`localhost`, `127.x.x.x`, `[::1]`), link-local addresses (`169.254.x.x`, `fe80::/10`), and private/unique-local ranges (`10.x`, `172.16-31.x`, `192.168.x`, `fc00::/7`). The protocol allow-list remains caller-scoped, so `data:` URIs used for adaptive-card icons are unaffected.
+- Markdown rendering uses `markdown-it` (zero preset) wrapped with `DOMPurify.sanitize` before `dangerouslySetInnerHTML` — malicious HTML/script is neutralized while supported formatting (emphasis, links, lists, strikethrough) is preserved.
- Adaptive cards render templated JSON — validate card payload at adapter/host layer.
-Evidence: `src/util.js`, `package.json` dependencies.
+Evidence: `src/util.js`, `src/components/adaptive-cards/Markdown/Markdown.jsx`, `package.json` dependencies.
## Known Sensitive Areas & Accepted Risks
diff --git a/docs/bundle-analysis-esm.html b/docs/bundle-analysis-esm.html
index 51e796c0e..15650defc 100644
--- a/docs/bundle-analysis-esm.html
+++ b/docs/bundle-analysis-esm.html
@@ -2694,7 +2694,7 @@
safe text');
+ const html = getHtml(renderer);
+
+ // No actual