diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml new file mode 100644 index 00000000000..aa0c5b581c1 --- /dev/null +++ b/.github/workflows/dependency-audit.yml @@ -0,0 +1,171 @@ +name: Dependency Security Audit + +on: + pull_request: + branches: [main, dev, staging] + + push: + branches: [main, dev, staging] + + schedule: + - cron: '0 9 * * 1' # 9 AM UTC every Monday + + workflow_dispatch: + +permissions: + contents: read + security-events: write + pull-requests: write + +concurrency: + group: dependency-audit-${{ github.ref }} + cancel-in-progress: true + +jobs: + audit: + name: Dependency Vulnerability Audit + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.x + cache: 'yarn' + + - name: Install dependencies + run: yarn --immutable + + - name: Run Yarn Audit + id: yarn-audit + run: | + echo "Running yarn npm audit..." + yarn npm audit --all --recursive --json > audit-results.json || true + + # Parse results + CRITICAL=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.critical // 0') + HIGH=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.high // 0') + MODERATE=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.moderate // 0') + LOW=$(cat audit-results.json | jq -r '.metadata.vulnerabilities.low // 0') + + echo "critical=$CRITICAL" >> $GITHUB_OUTPUT + echo "high=$HIGH" >> $GITHUB_OUTPUT + echo "moderate=$MODERATE" >> $GITHUB_OUTPUT + echo "low=$LOW" >> $GITHUB_OUTPUT + + # Create summary + echo "## Dependency Audit Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Severity | Count |" >> $GITHUB_STEP_SUMMARY + echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| 🔴 Critical | $CRITICAL |" >> $GITHUB_STEP_SUMMARY + echo "| 🟠 High | $HIGH |" >> $GITHUB_STEP_SUMMARY + echo "| 🟡 Moderate | $MODERATE |" >> $GITHUB_STEP_SUMMARY + echo "| 🟢 Low | $LOW |" >> $GITHUB_STEP_SUMMARY + + # Generate detailed report + yarn npm audit --all --recursive > audit-report.txt || true + + - name: Upload audit results + uses: actions/upload-artifact@v4 + with: + name: dependency-audit-results + path: | + audit-results.json + audit-report.txt + retention-days: 30 + + - name: Check for critical vulnerabilities + if: steps.yarn-audit.outputs.critical != '0' + run: | + echo "::error::Found ${{ steps.yarn-audit.outputs.critical }} critical vulnerabilities!" + echo "Please review the audit results and update vulnerable dependencies." + cat audit-report.txt + exit 1 + + - name: Check for high vulnerabilities + if: steps.yarn-audit.outputs.high != '0' + run: | + echo "::warning::Found ${{ steps.yarn-audit.outputs.high }} high severity vulnerabilities!" + echo "Please review the audit results and plan updates for vulnerable dependencies." + cat audit-report.txt + + - name: Comment on PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const auditResults = JSON.parse(fs.readFileSync('audit-results.json', 'utf8')); + const vulns = auditResults.metadata.vulnerabilities; + + const critical = vulns.critical || 0; + const high = vulns.high || 0; + const moderate = vulns.moderate || 0; + const low = vulns.low || 0; + + let status = '✅ No vulnerabilities found'; + let emoji = '✅'; + + if (critical > 0) { + status = `🔴 ${critical} critical vulnerabilities found`; + emoji = '🔴'; + } else if (high > 0) { + status = `🟠 ${high} high severity vulnerabilities found`; + emoji = '🟠'; + } else if (moderate > 0) { + status = `🟡 ${moderate} moderate vulnerabilities found`; + emoji = '🟡'; + } else if (low > 0) { + status = `🟢 ${low} low severity vulnerabilities found`; + emoji = '🟢'; + } + + const comment = `## ${emoji} Dependency Security Audit + + ${status} + + | Severity | Count | + |----------|-------| + | 🔴 Critical | ${critical} | + | 🟠 High | ${high} | + | 🟡 Moderate | ${moderate} | + | 🟢 Low | ${low} | + + ${critical > 0 ? '⚠️ **Action Required:** Critical vulnerabilities must be resolved before merging.' : ''} + ${high > 0 ? '⚠️ **Recommended:** High severity vulnerabilities should be addressed.' : ''} + +
+ View full audit report + + \`\`\` + ${fs.readFileSync('audit-report.txt', 'utf8').slice(0, 5000)} + \`\`\` + +
+ `; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Dependency Review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + comment-summary-in-pr: true diff --git a/electron/src/lib/openGraph.ts b/electron/src/lib/openGraph.ts index 5c16b9d108f..e1fcc150b5a 100644 --- a/electron/src/lib/openGraph.ts +++ b/electron/src/lib/openGraph.ts @@ -31,7 +31,8 @@ import {config} from '../settings/config'; const logger = getLogger(path.basename(__filename)); -axios.defaults.adapter = require('axios/lib/adapters/http'); // always use Node.js adapter +// In axios 1.x, the http adapter is used by default in Node.js environment +// No need to explicitly set it anymore const arrayify = (value: T[] | T = []): T[] => (Array.isArray(value) ? value : [value]); diff --git a/package.json b/package.json index f81320f80bb..cc62291906e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,8 @@ { "author": "Wire Swiss ", + "resolutions": { + "form-data": ">=2.5.4" + }, "dependencies": { "@hapi/joi": "17.1.1", "@wireapp/certificate-check": "0.7.20", @@ -8,7 +11,7 @@ "@wireapp/react-ui-kit": "9.59.1", "@wireapp/webapp-events": "0.28.1", "auto-launch": "5.0.6", - "axios": "0.21.2", + "axios": "1.12.2", "content-type": "1.0.5", "electron-dl": "^3.5.2", "electron-window-state": "5.0.3", @@ -115,7 +118,7 @@ "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "lint-staged": "15.5.2", - "mocha": "10.8.2", + "mocha": "^10.8.2", "nock": "13.5.6", "nyc": "15.1.0", "prettier": "2.8.8", diff --git a/yarn.lock b/yarn.lock index c43f18cbb4c..36fbd808e49 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5221,15 +5221,6 @@ __metadata: languageName: node linkType: hard -"axios@npm:0.21.2": - version: 0.21.2 - resolution: "axios@npm:0.21.2" - dependencies: - follow-redirects: ^1.14.0 - checksum: 41299c21f77323e7c56ea49d2d5ed25407d24bb145a4ce3441a8db17359ae56554f9495dca6e15d343a9530e106212a684c75a4db3bedfbe19f6414a8d94378e - languageName: node - linkType: hard - "axios@npm:1.12.2": version: 1.12.2 resolution: "axios@npm:1.12.2" @@ -6099,7 +6090,7 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6": +"combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -8649,7 +8640,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.6": +"follow-redirects@npm:^1.15.6": version: 1.15.11 resolution: "follow-redirects@npm:1.15.11" peerDependenciesMeta: @@ -8695,7 +8686,7 @@ __metadata: languageName: node linkType: hard -"form-data@npm:4.0.4, form-data@npm:^4.0.0, form-data@npm:^4.0.4": +"form-data@npm:>=2.5.4": version: 4.0.4 resolution: "form-data@npm:4.0.4" dependencies: @@ -8708,17 +8699,6 @@ __metadata: languageName: node linkType: hard -"form-data@npm:~2.3.2": - version: 2.3.3 - resolution: "form-data@npm:2.3.3" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 10c1780fa13dbe1ff3100114c2ce1f9307f8be10b14bf16e103815356ff567b6be39d70fc4a40f8990b9660012dc24b0f5e1dde1b6426166eb23a445ba068ca3 - languageName: node - linkType: hard - "fromentries@npm:^1.2.0": version: 1.3.2 resolution: "fromentries@npm:1.3.2" @@ -12054,37 +12034,6 @@ __metadata: languageName: node linkType: hard -"mocha@npm:10.8.2": - version: 10.8.2 - resolution: "mocha@npm:10.8.2" - dependencies: - ansi-colors: ^4.1.3 - browser-stdout: ^1.3.1 - chokidar: ^3.5.3 - debug: ^4.3.5 - diff: ^5.2.0 - escape-string-regexp: ^4.0.0 - find-up: ^5.0.0 - glob: ^8.1.0 - he: ^1.2.0 - js-yaml: ^4.1.0 - log-symbols: ^4.1.0 - minimatch: ^5.1.6 - ms: ^2.1.3 - serialize-javascript: ^6.0.2 - strip-json-comments: ^3.1.1 - supports-color: ^8.1.1 - workerpool: ^6.5.1 - yargs: ^16.2.0 - yargs-parser: ^20.2.9 - yargs-unparser: ^2.0.0 - bin: - _mocha: bin/_mocha - mocha: bin/mocha.js - checksum: 68cb519503f1e8ffd9b0651e1aef75dfe4754425186756b21e53169da44b5bcb1889e2b743711205082763d3f9a42eb8eb2c13bb1a718a08cb3a5f563bfcacdc - languageName: node - linkType: hard - "mocha@npm:=10.4.0": version: 10.4.0 resolution: "mocha@npm:10.4.0" @@ -12116,6 +12065,37 @@ __metadata: languageName: node linkType: hard +"mocha@npm:^10.8.2": + version: 10.8.2 + resolution: "mocha@npm:10.8.2" + dependencies: + ansi-colors: ^4.1.3 + browser-stdout: ^1.3.1 + chokidar: ^3.5.3 + debug: ^4.3.5 + diff: ^5.2.0 + escape-string-regexp: ^4.0.0 + find-up: ^5.0.0 + glob: ^8.1.0 + he: ^1.2.0 + js-yaml: ^4.1.0 + log-symbols: ^4.1.0 + minimatch: ^5.1.6 + ms: ^2.1.3 + serialize-javascript: ^6.0.2 + strip-json-comments: ^3.1.1 + supports-color: ^8.1.1 + workerpool: ^6.5.1 + yargs: ^16.2.0 + yargs-parser: ^20.2.9 + yargs-unparser: ^2.0.0 + bin: + _mocha: bin/_mocha + mocha: bin/mocha.js + checksum: 68cb519503f1e8ffd9b0651e1aef75dfe4754425186756b21e53169da44b5bcb1889e2b743711205082763d3f9a42eb8eb2c13bb1a718a08cb3a5f563bfcacdc + languageName: node + linkType: hard + "modify-filename@npm:^1.1.0": version: 1.1.0 resolution: "modify-filename@npm:1.1.0" @@ -16391,7 +16371,7 @@ __metadata: adm-zip: 0.5.16 auto-launch: 5.0.6 aws-sdk: 2.1692.0 - axios: 0.21.2 + axios: 1.12.2 babel-core: 7.0.0-bridge.0 babel-eslint: 10.1.0 babel-jest: 29.7.0 @@ -16445,7 +16425,7 @@ __metadata: lodash: 4.17.21 logdown: 3.3.1 minimist: 1.2.8 - mocha: 10.8.2 + mocha: ^10.8.2 nock: 13.5.6 nyc: 15.1.0 open-graph: 0.2.6