Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
@@ -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.' : ''}

<details>
<summary>View full audit report</summary>

\`\`\`
${fs.readFileSync('audit-report.txt', 'utf8').slice(0, 5000)}
\`\`\`

</details>
`;

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
3 changes: 2 additions & 1 deletion electron/src/lib/openGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@

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 = <T>(value: T[] | T = []): T[] => (Array.isArray(value) ? value : [value]);

Expand Down Expand Up @@ -104,7 +105,7 @@
};

export const axiosWithContentLimit = async (config: AxiosRequestConfig, contentLimit: number): Promise<string> => {
const cancelSource = axios.CancelToken.source();

Check warning on line 108 in electron/src/lib/openGraph.ts

View workflow job for this annotation

GitHub Actions / lint

Caution: `axios` also has a named export `CancelToken`. Check if you meant to write `import {CancelToken} from 'axios'` instead

Check warning on line 108 in electron/src/lib/openGraph.ts

View workflow job for this annotation

GitHub Actions / lint

Caution: `axios` also has a named export `CancelToken`. Check if you meant to write `import {CancelToken} from 'axios'` instead

config.responseType = 'stream';
config.cancelToken = cancelSource.token;
Expand Down Expand Up @@ -154,7 +155,7 @@

return body;
} catch (error: any) {
if (axios.isCancel(error)) {

Check warning on line 158 in electron/src/lib/openGraph.ts

View workflow job for this annotation

GitHub Actions / lint

Caution: `axios` also has a named export `isCancel`. Check if you meant to write `import {isCancel} from 'axios'` instead

Check warning on line 158 in electron/src/lib/openGraph.ts

View workflow job for this annotation

GitHub Actions / lint

Caution: `axios` also has a named export `isCancel`. Check if you meant to write `import {isCancel} from 'axios'` instead
return '';
}

Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"author": "Wire Swiss <[email protected]>",
"resolutions": {
"form-data": ">=2.5.4"
},
"dependencies": {
"@hapi/joi": "17.1.1",
"@wireapp/certificate-check": "0.7.20",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -125,7 +128,7 @@
"style-loader": "4.0.0",
"ts-node": "10.9.2",
"typescript": "5.9.3",
"webpack": "5.102.0",
"webpack": "^5.102.0",
"webpack-cli": "5.1.4"
},
"homepage": "https://wire.com",
Expand Down
96 changes: 38 additions & 58 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -6068,7 +6059,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:
Expand Down Expand Up @@ -8611,7 +8602,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:
Expand Down Expand Up @@ -8657,7 +8648,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:
Expand All @@ -8670,17 +8661,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"
Expand Down Expand Up @@ -12016,37 +11996,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"
Expand Down Expand Up @@ -12078,6 +12027,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"
Expand Down Expand Up @@ -16086,7 +16066,7 @@ __metadata:
languageName: node
linkType: hard

"webpack@npm:5.102.0":
"webpack@npm:^5.102.0":
version: 5.102.0
resolution: "webpack@npm:5.102.0"
dependencies:
Expand Down Expand Up @@ -16334,7 +16314,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
Expand Down Expand Up @@ -16388,7 +16368,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
Expand All @@ -16407,7 +16387,7 @@ __metadata:
typescript: 5.9.3
uuid: 9.0.1
validator: ^13.15.15
webpack: 5.102.0
webpack: ^5.102.0
webpack-cli: 5.1.4
xss: ^1.0.15
languageName: unknown
Expand Down
Loading