Skip to main content

security-alerts

Fetch all open security alerts from S360/ADO, Dependabot, and npm audit, apply all fixes, verify, commit, and create a PR.

Source facts

Repository
microsoft/powerplatform-build-tools
Last source activity
August 14, 2026 at 01:23
Detected SKILL.md language
English
Stars
310
Forks
71

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
security-alerts
description
Fetch all open security alerts from S360/ADO, Dependabot, and npm audit, apply all fixes, verify, commit, and create a PR.
user-invocable
true
# Security Alerts Fetch all open security alerts from S360/ADO, GitHub Dependabot, and npm audit. Merge into one fix plan, apply all fixes, verify build, commit, and create a PR. No user input required. **S360 service name for this repo:** `Power Apps App Deployment` **For local-only npm audit fixes without ADO/GitHub queries, use `/fix-dependencies` instead.** --- ## Step 1 — Gather alerts from all three sources (run in parallel) ### 1a — S360 / Component Governance ADO items Run two queries in parallel — S360 alerts live in both area paths: ```bash # Query 1 — PPBT Extensions area path az boards query --wiql " SELECT [System.Id], [System.Title], [System.State], [System.Tags], [Microsoft.VSTS.Common.Priority], [System.ChangedDate] FROM WorkItems WHERE [System.AreaPath] UNDER 'OneCRM\Client\UnifiedClient\AppLifeCycle\PPBT Extensions' AND [System.State] NOT IN ('Closed', 'Resolved', 'Done') AND ( [System.Tags] CONTAINS 'S360' OR [System.Tags] CONTAINS 'Component Governance' OR [System.Tags] CONTAINS 'SDL' OR [System.Title] CONTAINS 'CVE' OR [System.Title] CONTAINS 'GHSA' ) ORDER BY [Microsoft.VSTS.Common.Priority] ASC " --output json 2>&1 # Query 2 — Deployment Hub\Admin area path (where most S360 alerts are generated) az boards query --wiql " SELECT [System.Id], [System.Title], [System.State], [System.Tags], [Microsoft.VSTS.Common.Priority], [System.ChangedDate] FROM WorkItems WHERE [System.AreaPath] UNDER 'OneCRM\Client\UnifiedClient\AppLifeCycle\Deployment Hub\Admin' AND [System.State] NOT IN ('Closed', 'Resolved', 'Done') AND ( [System.Tags] CONTAINS 'S360' OR [System.Tags] CONTAINS 'Component Governance' OR [System.Tags] CONTAINS 'SDL' OR [System.Title] CONTAINS 'CVE' OR [System.Title] CONTAINS 'GHSA' ) ORDER BY [Microsoft.VSTS.Common.Priority] ASC " --output json 2>&1 ``` Merge results from both queries, deduplicate by ID. Fetch full detail for each result to get required package version: ```bash az boards work-item show --id <id> 2>&1 ``` If ADO auth unavailable: note "S360 skipped — ADO auth unavailable" and continue. S360 compliance versions take precedence over npm audit minimums — use the highest required version across all sources. ### 1b — GitHub Dependabot alerts ```bash gh api repos/microsoft/powerplatform-build-tools/dependabot/alerts \ --paginate \ --jq '.[] | select(.state == "open") | { number: .number, severity: .security_advisory.severity, package: .dependency.package.name, vulnerable_range: .security_vulnerability.vulnerable_version_range, patched_version: .security_vulnerability.first_patched_version.identifier, manifest: .dependency.manifest_path, scope: .dependency.scope, ghsa: .security_advisory.ghsa_id }' 2>&1 ``` If auth fails: run `gh auth login --hostname github.com --git-protocol https --web` (browser flow, no prompts) and retry once. If still fails, note "Dependabot skipped — GitHub auth unavailable" and continue. ### 1c — npm audit ```bash npm audit --json 2>&1 ``` ### 1d — Map S360 CVE/GHSA ids to packages Most `[S360]` items carry only a Component Governance `alertId` and no package name, and the Component Governance REST API is not reachable (`_apis/governance/...` returns 404). Resolve them against the GitHub Advisory DB instead — this reliably yields the package, the vulnerable range, and the real patched version: ```bash # From a CVE id (as it appears in the S360 work item title) gh api "/advisories?cve_id=CVE-2026-14257" \ --jq '.[0] | "\(.ghsa_id) | \(.severity) | " + ([.vulnerabilities[]? | "\(.package.name) vuln=\(.vulnerable_version_range) patched=\(.first_patched_version)"] | join(" ;; "))' # From a GHSA id gh api /advisories/GHSA-5c6j-r48x-rmvq \ --jq '"\(.severity) | " + ([.vulnerabilities[]? | "\(.package.name) patched=\(.first_patched_version)"] | join(" ;; "))' ``` Do this for every unmapped S360 item before declaring anything unresolvable. --- ## Step 1e — Run the resolver script first `scripts/audit-overrides.js` already does steps 2 and 3 mechanically: it reads `npm audit`, resolves every advisory against the Advisory DB, compares against each installed copy in the lock file, and reports exactly which ranges need to move. ```bash node scripts/audit-overrides.js # report only node scripts/audit-overrides.js --write # apply the safe override bumps ``` Use its output as the fix plan, then hand-fix only what it lists under **Needs a human**. **Check the existing range before editing `package.json`.** Most alerts here are a stale lock file, not a too-low range — e.g. `postcss` at `^8.5.15` already permits the patched `8.5.25`. For those, `npm update` is the entire fix and `package.json` should not be touched. --- ## Step 2 — Build fix plan Merge all three sources, deduplicate by package. Use the highest required version across sources. Print the plan then immediately proceed to Step 3 — do not wait: | Package | Current | Fix To | Strategy | Source | ADO Item | | ------- | ------- | ------ | -------- | ------ | -------- | | ... | ... | ... | A/B/C/D | S360/Dependabot/npm | #id or — | Decision rules per vulnerability: | Condition | Action | | --------- | ------ | | `patched_version` exists | Fix it — any semver jump acceptable | | `inBundle: true`, parent upgradeable | Upgrade parent (Strategy B) | | `inBundle: true`, no parent upgrade | Patch lock file (Strategy C) | | `patched_version: null` | Accept risk, document | | `scope: development` + low + no patch | Accept risk | Known permanent accepted risk — skip: `elliptic` (GHSA-848j-6mx2-7j84) — dev-only, no patched version. **"No published fix" may just be feed lag.** This machine resolves npm through the 1ES feed mirror (`ms-feed-*.pkgs.visualstudio.com`), which can trail the public registry by days. Before recording something as an accepted risk, cross-check against Dependabot — if Dependabot has opened a PR for a version `npm view` says does not exist, the fix is real and the mirror is simply behind. Say "not yet on our feed mirror", not "no fix exists", and let the Dependabot PR land it. --- ## Step 3 — Apply fixes ### Strategy A — npm override ```bash npm view <pkg>@<version> version # edit package.json overrides npm install 2>&1 npm ls <pkg> 2>&1 ``` Hard rules: - Never add `"minimatch": "^3.x"` flat override — infinite npm loop - `ajv` stays at `^6.x` — v8 breaks ESLint - Do not change: `nanoid`, `electron-to-chromium`, `@types/node` overrides - **Never add a flat override for a package installed across several major lines** — it rewrites every copy and silently downgrades the other lines. `brace-expansion` is installed on the 1.x, 2.x and 5.x lines simultaneously; each needs its own nested override. ### Strategy B — Direct dependency bump Update `package.json` version, then `npm install`. ### Strategy C — Lock file patch (`inBundle: true`) ```bash node -e " const l = require('./package-lock.json'); console.log( Object.keys(l.packages) .filter(k => k.endsWith('/<pkg>')) .map(k => k + ' -> ' + l.packages[k].version + ' inBundle:' + l.packages[k].inBundle) .join('\n') );" npm view <pkg>@<patched-version> dist.tarball dist.integrity --json node -e " const fs = require('fs'); const l = require('./package-lock.json'); Object.keys(l.packages) .filter(k => k.endsWith('/<pkg>')) .forEach(k => { l.packages[k].version = '<patched-version>'; l.packages[k].resolved = '<tarball-url>'; l.packages[k].integrity = '<integrity>'; }); fs.writeFileSync('./package-lock.json', JSON.stringify(l, null, 2) + '\n'); " npm install 2>&1 ``` --- ## Step 4 — Verify ```bash npm audit 2>&1 npm run ci 2>&1 ``` Functional tests fail locally (require `PA_BT_ORG_PASSWORD`) — expected, not a blocker. If any other step fails, fix it and re-run before continuing. Do not commit a broken build. --- ## Step 5 — Update ADO S360 items (only if Step 4 passes) For each S360 ADO item whose package was fixed: ```bash az boards work-item update --id <id> \ --discussion "Fixed by upgrading <package> from <old> to <new>. npm audit clean." 2>&1 az boards work-item update --id <id> --state "Resolved" 2>&1 ``` If the fix only partially satisfies S360 (e.g. patched CVE but higher version needed): add a comment, leave open, add to Follow-ups. Skip if ADO auth unavailable. --- ## Step 6 — Commit and PR (only if Step 4 passes) ```bash git add package.json package-lock.json git status git commit -m "chore: fix dependency vulnerabilities" ``` Then run `/create-pr` to create the pull request. --- ## Final Summary - **Fixed:** package, old → new, strategy, source (S360/Dependabot/npm audit) - **S360 items closed:** ADO ID, package, action taken - **Accepted risk:** package, GHSA ID, reason - **Follow-ups:** partial fixes, deferred items
View on GitHub