From 5db8d826835d5d6180d843752583de9e786ca170 Mon Sep 17 00:00:00 2001 From: Dima Birenbaum Date: Mon, 13 Apr 2026 09:20:21 +0300 Subject: [PATCH 1/3] feat(bot): add tool configuration knowledge to triage bot (#237) * feat(bot): add tool configuration knowledge to triage bot prompt * fix(ci): grant issues write permission to triage bot workflow * fix(bot): recompile lock file, revert issues:write from .md (handled by safe-outputs) --------- Co-authored-by: Dima Birenbaum --- .../workflows/msdo-issue-assistant.lock.yml | 8 +- .github/workflows/msdo-issue-assistant.md | 79 ++++++++++++++++++- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/.github/workflows/msdo-issue-assistant.lock.yml b/.github/workflows/msdo-issue-assistant.lock.yml index d54a8b3b..771daac4 100644 --- a/.github/workflows/msdo-issue-assistant.lock.yml +++ b/.github/workflows/msdo-issue-assistant.lock.yml @@ -21,7 +21,7 @@ # For more information: https://github.github.com/gh-aw/introduction/overview/ # # -# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"be9d9a34c65ac1897e69366960562c46d72ff703a7ca2bcec2adf25f114a1707","compiler_version":"v0.61.0","strict":true} +# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"b9853605bc6fd41a4d81ec4728106d1ffdc01e2dbcf460d6aaea1620c94a3367","compiler_version":"v0.61.0","strict":true} name: "MSDO Issue Triage Assistant" "on": @@ -336,7 +336,7 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF' - {"add_comment":{"max":4},"add_labels":{"allowed":["type:bug","type:feature","type:docs","type:question","type:security","type:maintenance","status:triage","status:waiting-on-author","status:repro-needed","status:team-review"],"max":3},"missing_data":{},"missing_tool":{}} + {"add_comment":{"max":4},"add_labels":{"allowed":["type:bug","type:feature","type:docs","type:question","type:security","type:maintenance","status:triage","status:waiting-on-author","status:repro-needed","status:team-review","area:action","area:msdo-cli","area:ci","area:container-mapping"],"max":3},"missing_data":{},"missing_tool":{}} GH_AW_SAFE_OUTPUTS_CONFIG_EOF - name: Write Safe Outputs Tools run: | @@ -344,7 +344,7 @@ jobs: { "description_suffixes": { "add_comment": " CONSTRAINTS: Maximum 4 comment(s) can be added.", - "add_labels": " CONSTRAINTS: Only these labels are allowed: [\"type:bug\" \"type:feature\" \"type:docs\" \"type:question\" \"type:security\" \"type:maintenance\" \"status:triage\" \"status:waiting-on-author\" \"status:repro-needed\" \"status:team-review\"]." + "add_labels": " CONSTRAINTS: Only these labels are allowed: [\"type:bug\" \"type:feature\" \"type:docs\" \"type:question\" \"type:security\" \"type:maintenance\" \"status:triage\" \"status:waiting-on-author\" \"status:repro-needed\" \"status:team-review\" \"area:action\" \"area:msdo-cli\" \"area:ci\" \"area:container-mapping\"]." }, "repo_params": {}, "dynamic_tools": [] @@ -981,7 +981,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,codeload.github.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,lfs.github.com,objects.githubusercontent.com,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":4},\"add_labels\":{\"allowed\":[\"type:bug\",\"type:feature\",\"type:docs\",\"type:question\",\"type:security\",\"type:maintenance\",\"status:triage\",\"status:waiting-on-author\",\"status:repro-needed\",\"status:team-review\"]},\"missing_data\":{},\"missing_tool\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":4},\"add_labels\":{\"allowed\":[\"type:bug\",\"type:feature\",\"type:docs\",\"type:question\",\"type:security\",\"type:maintenance\",\"status:triage\",\"status:waiting-on-author\",\"status:repro-needed\",\"status:team-review\",\"area:action\",\"area:msdo-cli\",\"area:ci\",\"area:container-mapping\"]},\"missing_data\":{},\"missing_tool\":{}}" with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/msdo-issue-assistant.md b/.github/workflows/msdo-issue-assistant.md index 6a985d6c..18cd4ca5 100644 --- a/.github/workflows/msdo-issue-assistant.md +++ b/.github/workflows/msdo-issue-assistant.md @@ -34,7 +34,7 @@ safe-outputs: add-comment: max: 4 add-labels: - allowed: ["type:bug", "type:feature", "type:docs", "type:question", "type:security", "type:maintenance", "status:triage", "status:waiting-on-author", "status:repro-needed", "status:team-review"] + allowed: ["type:bug", "type:feature", "type:docs", "type:question", "type:security", "type:maintenance", "status:triage", "status:waiting-on-author", "status:repro-needed", "status:team-review", "area:action", "area:msdo-cli", "area:ci", "area:container-mapping"] --- @@ -44,9 +44,10 @@ You are an issue triage assistant for the **Microsoft Security DevOps (MSDO)** C ## Your Knowledge Base -Before responding, fetch wiki content from: +Use the fetch tool to retrieve these wiki pages before responding: - https://raw.githubusercontent.com/wiki/microsoft/security-devops-action/Home.md - https://raw.githubusercontent.com/wiki/microsoft/security-devops-action/FAQ.md +- https://raw.githubusercontent.com/wiki/microsoft/security-devops-action/Tool-Configuration.md MSDO is a command line tool that integrates security analysis tools into CI/CD pipelines. @@ -62,6 +63,77 @@ MSDO is a command line tool that integrates security analysis tools into CI/CD p **Wiki reference:** https://github.com/microsoft/security-devops-action/wiki +## Tool Configuration Reference + +MSDO supports passing arguments to individual tools via environment variables or `.gdnconfig` files. + +**Environment variable pattern:** `GDN__` + +Where `` is uppercase and `` is PascalCase with no separators. + +**Common examples:** + +Checkov: +```yaml +env: + GDN_CHECKOV_DOWNLOADEXTERNALMODULES: "true" # download external Terraform modules + GDN_CHECKOV_FRAMEWORK: "terraform" # limit scan to specific framework + GDN_CHECKOV_SKIPCHECK: "CKV_AWS_1,CKV_AWS_2" # skip specific checks + GDN_CHECKOV_CONFIGFILE: ".checkov.yml" # use a checkov config file +``` + +Trivy: +```yaml +env: + GDN_TRIVY_SEVERITIES: "HIGH,CRITICAL" # filter by severity + GDN_TRIVY_IGNOREUNFIXED: "true" # ignore unfixed vulnerabilities + GDN_TRIVY_SCANNERS: "vuln,secret" # specify scanner types +``` + +ESLint: +```yaml +env: + GDN_ESLINT_CONFIGURATIONFILE: ".eslintrc.js" # custom ESLint config + GDN_ESLINT_QUIET: "true" # suppress warnings +``` + +Terrascan: +```yaml +env: + GDN_TERRASCAN_IACTYPE: "terraform" # specify IaC type + GDN_TERRASCAN_SEVERITY: "HIGH" # minimum severity + GDN_TERRASCAN_SKIPRULES: "AC_AWS_001" # skip specific rules +``` + +**`.gdnconfig` alternative** (for complex multi-tool configs): +```json +{ + "fileVersion": "1.0.0", + "jobs": [{ + "tools": [{ + "tool": { "name": "checkov" }, + "arguments": { + "DownloadExternalModules": { "values": ["true"] }, + "Framework": { "values": ["terraform"] } + } + }] + }] +} +``` + +Referenced via: +```yaml +- uses: microsoft/security-devops-action@latest + with: + config: '.msdo.gdnconfig' +``` + +When a user asks about tool-specific flags or arguments: +1. Suggest the environment variable approach first (simplest) +2. Mention `.gdnconfig` as an alternative for complex setups +3. Link to the [Tool Configuration wiki page](https://github.com/microsoft/security-devops-action/wiki/Tool-Configuration) +4. Add the `area:msdo-cli` label since tool configuration is handled by the CLI + ## Your Task When a new issue is opened or a user comments: @@ -120,6 +192,9 @@ Keep responses: **User asks:** "What tools does MSDO support?" **Response:** MSDO supports these security analysis tools: antimalware (Windows only), bandit, binskim, checkov, eslint, templateanalyzer, terrascan, and trivy. Tools are automatically detected based on your repository content, or you can specify them explicitly. See the [Tools documentation](https://github.com/microsoft/security-devops-action/wiki) for details. +**User asks:** "How do I pass --download-external-modules to checkov?" +**Response:** You can enable this by setting an environment variable in your workflow: `GDN_CHECKOV_DOWNLOADEXTERNALMODULES: "true"` in the `env:` block of the MSDO action step. MSDO supports passing arguments to tools via the `GDN__` pattern. See the [Tool Configuration](https://github.com/microsoft/security-devops-action/wiki/Tool-Configuration) wiki page for more examples. + **User reports:** "Trivy is failing with container image not found" **Response:** This error typically occurs when Docker isn't available. Trivy requires Docker for container scanning. Please ensure you have `docker/setup-buildx-action@v3` in your workflow before the MSDO action. Can you share your workflow YAML so I can help verify the configuration? From 887bc61ff32cbdaec5a745e3fea22777a0fd0c3d Mon Sep 17 00:00:00 2001 From: Dima Birenbaum Date: Mon, 13 Apr 2026 09:31:06 +0300 Subject: [PATCH 2/3] fix(deps): add npm overrides to resolve all open Dependabot security alerts (#234) --- package-lock.json | 224 ++++++++++++++-------------------------------- package.json | 6 +- 2 files changed, 71 insertions(+), 159 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c16c876..0c40d760 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,15 +62,6 @@ "integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==", "license": "MIT" }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, "node_modules/@gulpjs/messages": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", @@ -237,18 +228,6 @@ "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", "license": "MIT" }, - "node_modules/@microsoft/security-devops-actions-toolkit/node_modules/undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -584,9 +563,14 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/bare-events": { "version": "2.8.2", @@ -665,14 +649,16 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -842,11 +828,6 @@ "dev": true, "license": "MIT" }, - "node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "1.9.0", "dev": true, @@ -2274,14 +2255,19 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.5" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minipass": { @@ -2329,15 +2315,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/mocha/node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -2450,21 +2427,6 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "dev": true, @@ -2793,13 +2755,13 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -2911,16 +2873,6 @@ ], "license": "MIT" }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/readable-stream": { "version": "2.3.8", "dev": true, @@ -3144,13 +3096,13 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=20.0.0" } }, "node_modules/shebang-command": { @@ -3537,12 +3489,12 @@ } }, "node_modules/undici": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", - "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.0.2.tgz", + "integrity": "sha512-B9MeU5wuFhkFAuNeA19K2GDFcQXZxq33fL0nRy2Aq30wdufZbyyvxW3/ChaeipXVfy/wUweZyzovQGk39+9k2w==", "license": "MIT", "engines": { - "node": ">=18.17" + "node": ">=22.19.0" } }, "node_modules/undici-types": { @@ -3904,7 +3856,7 @@ "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==", "requires": { "tunnel": "^0.0.6", - "undici": "^6.23.0" + "undici": ">=6.24.1" } }, "@actions/io": { @@ -3912,11 +3864,6 @@ "resolved": "https://registry.npmjs.org/@actions/io/-/io-2.0.0.tgz", "integrity": "sha512-Jv33IN09XLO+0HS79aaODsvIRyduiF7NY/F6LYeK5oeUmrsz7aFdRphQjFoESF4jS7lMauDOttKALcpapVDIAg==" }, - "@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" - }, "@gulpjs/messages": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", @@ -4031,21 +3978,13 @@ "integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==", "requires": { "tunnel": "^0.0.6", - "undici": "^5.25.4" + "undici": ">=6.24.1" } }, "@actions/io": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==" - }, - "undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", - "requires": { - "@fastify/busboy": "^2.0.0" - } } } }, @@ -4194,7 +4133,7 @@ "dev": true, "requires": { "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "picomatch": ">=2.3.2" } }, "append-buffer": { @@ -4282,7 +4221,9 @@ } }, "balanced-match": { - "version": "1.0.2", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true }, "bare-events": { @@ -4329,13 +4270,12 @@ } }, "brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" } }, "braces": { @@ -4442,10 +4382,6 @@ "version": "1.1.4", "dev": true }, - "concat-map": { - "version": "0.0.1", - "dev": true - }, "convert-source-map": { "version": "1.9.0", "dev": true @@ -4782,7 +4718,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": ">=3.1.3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -5400,17 +5336,19 @@ "dev": true, "requires": { "braces": ">=3.0.3", - "picomatch": "^2.3.1" + "picomatch": ">=2.3.2" } }, "mimic-response": { "version": "4.0.0" }, "minimatch": { - "version": "3.1.2", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.5" } }, "minipass": { @@ -5436,10 +5374,10 @@ "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^9.0.5", + "minimatch": ">=3.1.3", "ms": "^2.1.3", "picocolors": "^1.1.1", - "serialize-javascript": "^6.0.2", + "serialize-javascript": ">=7.0.5", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^9.2.0", @@ -5448,15 +5386,6 @@ "yargs-unparser": "^2.0.0" }, "dependencies": { - "brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, "chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -5512,7 +5441,7 @@ "requires": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "minimatch": ">=3.1.3", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" @@ -5524,15 +5453,6 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, "ms": { "version": "2.1.3", "dev": true @@ -5746,9 +5666,9 @@ "dev": true }, "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true }, "plugin-error": { @@ -5818,15 +5738,6 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, "readable-stream": { "version": "2.3.8", "dev": true, @@ -5846,7 +5757,7 @@ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "picomatch": "^2.2.1" + "picomatch": ">=2.3.2" } }, "rechoir": { @@ -5973,13 +5884,10 @@ } }, "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "dev": true }, "shebang-command": { "version": "2.0.0", @@ -6252,9 +6160,9 @@ "dev": true }, "undici": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", - "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==" + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.0.2.tgz", + "integrity": "sha512-B9MeU5wuFhkFAuNeA19K2GDFcQXZxq33fL0nRy2Aq30wdufZbyyvxW3/ChaeipXVfy/wUweZyzovQGk39+9k2w==" }, "undici-types": { "version": "7.18.2", diff --git a/package.json b/package.json index fb866629..9f525a83 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,11 @@ "description": "Node dependencies for the microsoft/security-devops-action.", "overrides": { "braces": ">=3.0.3", - "micromatch": ">=4.0.8" + "micromatch": ">=4.0.8", + "picomatch": ">=2.3.2", + "minimatch": ">=3.1.3", + "serialize-javascript": ">=7.0.5", + "undici": ">=6.24.1" }, "scripts": { "build": "npx gulp", From 91a1da1d458f87adb54ade57e5f19ed44d71d56f Mon Sep 17 00:00:00 2001 From: Dima Birenbaum Date: Mon, 13 Apr 2026 09:40:46 +0300 Subject: [PATCH 3/3] fix(security): resolve ReDoS in image name validation regex (#243) Co-authored-by: Dima Birenbaum --- lib/v2/defender-helpers.js | 2 +- src/v2/defender-helpers.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/v2/defender-helpers.js b/lib/v2/defender-helpers.js index e31b7c96..f736eaf8 100644 --- a/lib/v2/defender-helpers.js +++ b/lib/v2/defender-helpers.js @@ -120,7 +120,7 @@ function validateImageName(imageName) { throw new Error('Image name cannot be empty for image scan'); } const trimmedImageName = imageName.trim(); - const imageNameRegex = /^(?:(?:[a-zA-Z0-9._-]+(?:\.[a-zA-Z0-9._-]+)*(?::[0-9]+)?\/)?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)*)(?::[a-zA-Z0-9._-]+|@sha256:[a-fA-F0-9]{64})?$/; + const imageNameRegex = /^(?:(?:[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*(?::[0-9]+)?\/)?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)*)(?::[a-zA-Z0-9._-]+|@sha256:[a-fA-F0-9]{64})?$/; if (!imageNameRegex.test(trimmedImageName)) { throw new Error(`Invalid image name format: ${trimmedImageName}. Image name should follow container image naming conventions.`); } diff --git a/src/v2/defender-helpers.ts b/src/v2/defender-helpers.ts index f230586e..d236c972 100644 --- a/src/v2/defender-helpers.ts +++ b/src/v2/defender-helpers.ts @@ -136,7 +136,7 @@ export function validateImageName(imageName: string): string { const trimmedImageName = imageName.trim(); - const imageNameRegex = /^(?:(?:[a-zA-Z0-9._-]+(?:\.[a-zA-Z0-9._-]+)*(?::[0-9]+)?\/)?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)*)(?::[a-zA-Z0-9._-]+|@sha256:[a-fA-F0-9]{64})?$/; + const imageNameRegex = /^(?:(?:[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*(?::[0-9]+)?\/)?[a-zA-Z0-9._-]+(?:\/[a-zA-Z0-9._-]+)*)(?::[a-zA-Z0-9._-]+|@sha256:[a-fA-F0-9]{64})?$/; if (!imageNameRegex.test(trimmedImageName)) { throw new Error(`Invalid image name format: ${trimmedImageName}. Image name should follow container image naming conventions.`);