Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
88291b9
chore: sync development → main (security audits + CVE patches) (#112)
tmcneil-mdb May 27, 2026
d7fbfa5
chore(java-spring): bump Spring Boot to 4.0.6 and refresh deps
dacharyc May 27, 2026
8d85506
Merge pull request #115 from mongodb/DOCSP-59938-main
dacharyc May 28, 2026
b7d997a
fix: resolve Dependabot security alerts across tanstack and python-fa…
cbullinger May 26, 2026
6fb26f7
fix(tanstack): align TanStack packages and fix unit test mocking
cbullinger May 26, 2026
d530ee3
fix(python-fastapi): bump fastapi and starlette for PYSEC-2026-161
cbullinger Jun 4, 2026
e766e53
Merge pull request #113 from mongodb/security/fix-dependabot-alerts
cbullinger Jun 4, 2026
b4b4425
chore(ci): add explicit GITHUB_TOKEN permissions to workflows
cbullinger Jun 4, 2026
bae04ff
fix(python-fastapi): stop exposing exception details in API errors
cbullinger Jun 4, 2026
b9b78c3
fix(java-spring): resolve CodeQL regex and redirect findings
cbullinger Jun 5, 2026
0b68b4d
fix(js-express): resolve CodeQL rate limit, regex, and query findings
cbullinger Jun 5, 2026
c58e427
fix(python-fastapi): address Copilot review on PR #117
cbullinger Jun 5, 2026
1dd77ef
test(python-fastapi): cover get_all_movies cursor iteration errors
cbullinger Jun 5, 2026
d878893
fix(js-express): address Copilot review on PR #119
cbullinger Jun 5, 2026
1940d78
chore(ci): drop unnecessary actions: write from test workflows
cbullinger Jun 8, 2026
505eb44
chore(ci): add workflow to verify artifact upload permissions
cbullinger Jun 8, 2026
20ae2df
chore(ci): remove temporary artifact permissions verification workflow
cbullinger Jun 8, 2026
48c91c1
fix(python-fastapi): log Voyage AI authentication failures server-side
cbullinger Jun 8, 2026
5e93708
Merge pull request #118 from mongodb/fix/codeql-java-spring
cbullinger Jun 8, 2026
204389a
fix(js-express): address dacharyc review on PR #119
cbullinger Jun 8, 2026
660a48a
Merge pull request #117 from mongodb/fix/codeql-python-stack-trace
cbullinger Jun 8, 2026
6218d39
Merge pull request #119 from mongodb/fix/codeql-js-express
cbullinger Jun 8, 2026
569a7b3
Merge pull request #116 from mongodb/chore/workflow-permissions
cbullinger Jun 8, 2026
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
82 changes: 82 additions & 0 deletions .github/scripts/generate-audit-summary-npm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash
set -e

# Generate Security Audit Summary from npm audit JSON output
# Usage: ./generate-audit-summary-npm.sh <audit-json-file> <project-label>
# Example: ./generate-audit-summary-npm.sh audit-results.json "TanStack App"

# Guard: skip if GITHUB_STEP_SUMMARY is not set
if [ -z "$GITHUB_STEP_SUMMARY" ]; then
echo "Warning: GITHUB_STEP_SUMMARY not set, skipping summary generation"
exit 0
fi

AUDIT_JSON="${1:-}"
PROJECT_LABEL="${2:-npm project}"

if [ ! -f "$AUDIT_JSON" ]; then
echo "⚠️ Audit JSON file not found: $AUDIT_JSON" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi

echo "## 🔒 Security Audit — $PROJECT_LABEL" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

# Extract vulnerability counts from metadata
info=$(jq -r '.metadata.vulnerabilities.info // 0' "$AUDIT_JSON")
low=$(jq -r '.metadata.vulnerabilities.low // 0' "$AUDIT_JSON")
moderate=$(jq -r '.metadata.vulnerabilities.moderate // 0' "$AUDIT_JSON")
high=$(jq -r '.metadata.vulnerabilities.high // 0' "$AUDIT_JSON")
critical=$(jq -r '.metadata.vulnerabilities.critical // 0' "$AUDIT_JSON")
total=$(jq -r '.metadata.vulnerabilities.total // 0' "$AUDIT_JSON")

# Summary table
echo "### Vulnerability Summary" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Severity | Count |" >> "$GITHUB_STEP_SUMMARY"
echo "|----------|-------|" >> "$GITHUB_STEP_SUMMARY"
[ "$critical" -gt 0 ] && echo "| 🔴 Critical | $critical |" >> "$GITHUB_STEP_SUMMARY"
[ "$high" -gt 0 ] && echo "| 🟠 High | $high |" >> "$GITHUB_STEP_SUMMARY"
[ "$moderate" -gt 0 ] && echo "| 🟡 Moderate | $moderate |" >> "$GITHUB_STEP_SUMMARY"
[ "$low" -gt 0 ] && echo "| 🔵 Low | $low |" >> "$GITHUB_STEP_SUMMARY"
[ "$info" -gt 0 ] && echo "| ℹ️ Info | $info |" >> "$GITHUB_STEP_SUMMARY"
echo "| **Total** | **$total** |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

# If there are vulnerabilities, list them
if [ "$total" -gt 0 ]; then
echo "### Vulnerability Details" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Package | Severity | Fix Available | Details |" >> "$GITHUB_STEP_SUMMARY"
echo "|---------|----------|---------------|---------|" >> "$GITHUB_STEP_SUMMARY"

# Extract each vulnerability with a direct advisory (not just transitive references)
jq -r '
.vulnerabilities | to_entries[] |
.value |
select(.via | map(type) | any(. == "object")) |
{
name: .name,
severity: .severity,
fix: (if .fixAvailable == true then "✅ Yes"
elif .fixAvailable == false then "❌ No"
elif .fixAvailable != null then "✅ \(.fixAvailable.name)@\(.fixAvailable.version)"
else "❓ Unknown" end),
title: ([.via[] | select(type == "object") | .title] | first // "N/A")
} |
"| \(.name) | \(.severity) | \(.fix) | \(.title) |"
' "$AUDIT_JSON" >> "$GITHUB_STEP_SUMMARY" 2>/dev/null || true

echo "" >> "$GITHUB_STEP_SUMMARY"

# Action items
echo "### 🛠️ What to do" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "1. Run \`npm audit\` locally to see full details" >> "$GITHUB_STEP_SUMMARY"
echo "2. Run \`npm audit fix\` to auto-fix where possible" >> "$GITHUB_STEP_SUMMARY"
echo "3. For breaking fixes: \`npm audit fix --force\` (review changes carefully)" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "❌ **Audit failed — vulnerabilities found!**" >> "$GITHUB_STEP_SUMMARY"
else
echo "✅ **No vulnerabilities found!**" >> "$GITHUB_STEP_SUMMARY"
fi
68 changes: 68 additions & 0 deletions .github/scripts/generate-audit-summary-pip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/bin/bash
set -e

# Generate Security Audit Summary from pip-audit JSON output
# Usage: ./generate-audit-summary-pip.sh <audit-json-file> <project-label>
# Example: ./generate-audit-summary-pip.sh audit-results.json "Python FastAPI"

# Guard: skip if GITHUB_STEP_SUMMARY is not set
if [ -z "$GITHUB_STEP_SUMMARY" ]; then
echo "Warning: GITHUB_STEP_SUMMARY not set, skipping summary generation"
exit 0
fi

AUDIT_JSON="${1:-}"
PROJECT_LABEL="${2:-Python project}"

if [ ! -f "$AUDIT_JSON" ]; then
echo "⚠️ Audit JSON file not found: $AUDIT_JSON" >> "$GITHUB_STEP_SUMMARY"
exit 1
fi

echo "## 🔒 Security Audit — $PROJECT_LABEL" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

# pip-audit JSON structure: { "dependencies": [ { "name": "...", "version": "...", "vulns": [...] } ] }
# Count vulnerable packages (those with non-empty vulns arrays)
total_deps=$(jq '[.dependencies | length] | first // 0' "$AUDIT_JSON")
vuln_packages=$(jq '[.dependencies[] | select(.vulns | length > 0)] | length' "$AUDIT_JSON")
total_vulns=$(jq '[.dependencies[].vulns | length] | add // 0' "$AUDIT_JSON")

# Summary table
echo "### Vulnerability Summary" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Metric | Count |" >> "$GITHUB_STEP_SUMMARY"
echo "|--------|-------|" >> "$GITHUB_STEP_SUMMARY"
echo "| 📦 Total dependencies scanned | $total_deps |" >> "$GITHUB_STEP_SUMMARY"
echo "| ⚠️ Vulnerable packages | $vuln_packages |" >> "$GITHUB_STEP_SUMMARY"
echo "| 🔓 Total vulnerabilities | $total_vulns |" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"

# If there are vulnerabilities, list them
if [ "$total_vulns" -gt 0 ]; then
echo "### Vulnerability Details" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Package | Version | Vulnerability ID | Fix Versions |" >> "$GITHUB_STEP_SUMMARY"
echo "|---------|---------|-----------------|--------------|" >> "$GITHUB_STEP_SUMMARY"

jq -r '
.dependencies[] |
select(.vulns | length > 0) |
. as $dep |
.vulns[] |
"| \($dep.name) | \($dep.version) | \(.id) | \(.fix_versions | join(", ") // "N/A") |"
' "$AUDIT_JSON" >> "$GITHUB_STEP_SUMMARY" 2>/dev/null || true

echo "" >> "$GITHUB_STEP_SUMMARY"

# Action items
echo "### 🛠️ What to do" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "1. Update the affected packages in \`requirements.in\`" >> "$GITHUB_STEP_SUMMARY"
echo "2. Run \`pip-compile requirements.in\` to regenerate \`requirements.txt\`" >> "$GITHUB_STEP_SUMMARY"
echo "3. Run \`pip-audit -r requirements.txt\` locally to verify the fix" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "❌ **Audit failed — vulnerabilities found!**" >> "$GITHUB_STEP_SUMMARY"
else
echo "✅ **No vulnerabilities found!**" >> "$GITHUB_STEP_SUMMARY"
fi
3 changes: 3 additions & 0 deletions .github/workflows/Security-Notification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ on:
# Allows you to test manually
workflow_dispatch:

permissions:
contents: read

jobs:
check-alerts:
runs-on: ubuntu-latest
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/audit-python-fastapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Audit Python FastAPI Dependencies

on:
pull_request:
branches:
- development
paths:
- 'mflix/server/python-fastapi/**'

permissions:
contents: read

jobs:
audit:
name: pip-audit (Python FastAPI)
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install pip-audit
run: pip install pip-audit

- name: Audit dependencies
working-directory: mflix/server/python-fastapi
run: pip-audit -r requirements.txt --format json -o audit-results.json || true

- name: Generate audit summary
if: always()
run: |
chmod +x .github/scripts/generate-audit-summary-pip.sh
.github/scripts/generate-audit-summary-pip.sh \
mflix/server/python-fastapi/audit-results.json \
"Python FastAPI"

- name: Check for vulnerabilities
run: |
vuln_count=$(jq '[.dependencies[].vulns | length] | add // 0' mflix/server/python-fastapi/audit-results.json)
if [ "$vuln_count" -gt 0 ]; then
echo "❌ Found $vuln_count vulnerabilities"
exit 1
fi
echo "✅ No vulnerabilities found"
69 changes: 69 additions & 0 deletions .github/workflows/audit-tanstack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Audit TanStack Dependencies

on:
pull_request:
branches:
- development
- frameworks-tanstack
paths:
- 'frameworks/javascript/tanstack/**'

permissions:
contents: read

jobs:
audit:
name: npm audit (TanStack)
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies (app)
working-directory: frameworks/javascript/tanstack/app
run: npm install

- name: Audit app dependencies
working-directory: frameworks/javascript/tanstack/app
run: npm audit --json > audit-results-app.json || true

- name: Install dependencies (bluehawk)
working-directory: frameworks/javascript/tanstack
run: npm install

- name: Audit bluehawk dependencies
working-directory: frameworks/javascript/tanstack
run: npm audit --json > audit-results-bluehawk.json || true

- name: Generate audit summary (app)
if: always()
run: |
chmod +x .github/scripts/generate-audit-summary-npm.sh
.github/scripts/generate-audit-summary-npm.sh \
frameworks/javascript/tanstack/app/audit-results-app.json \
"TanStack App"

- name: Generate audit summary (bluehawk)
if: always()
run: |
chmod +x .github/scripts/generate-audit-summary-npm.sh
.github/scripts/generate-audit-summary-npm.sh \
frameworks/javascript/tanstack/audit-results-bluehawk.json \
"TanStack Bluehawk"

- name: Check for high+ vulnerabilities
run: |
app_high=$(jq -r '[(.metadata.vulnerabilities.high // 0), (.metadata.vulnerabilities.critical // 0)] | add' frameworks/javascript/tanstack/app/audit-results-app.json)
bh_high=$(jq -r '[(.metadata.vulnerabilities.high // 0), (.metadata.vulnerabilities.critical // 0)] | add' frameworks/javascript/tanstack/audit-results-bluehawk.json)
total=$((app_high + bh_high))
if [ "$total" -gt 0 ]; then
echo "❌ Found $total high/critical vulnerabilities"
exit 1
fi
echo "✅ No high/critical vulnerabilities found"
1 change: 1 addition & 0 deletions .github/workflows/new-issue-notify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
issues:
types: [opened]

permissions: {}

jobs:
notify_slack_on_issue:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/run-express-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:
paths:
- 'mflix/server/js-express/**'

permissions:
contents: read

jobs:
test:
name: Run Express Tests
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/run-java-spring-boot-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:
paths:
- 'mflix/server/java-spring/**'

permissions:
contents: read

jobs:
test:
name: Run Java Spring Boot Tests
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/run-python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:
paths:
- 'mflix/server/python-fastapi/**'

permissions:
contents: read

jobs:
test:
name: Run Python Tests
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/run-tanstack-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ on:
paths:
- 'frameworks/javascript/tanstack/**'

permissions:
contents: read

jobs:
test:
name: Run TanStack Tests
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Thumbs.db
logs/
*.log


# Temporary Files (Global)
*.tmp
*.temp
Expand All @@ -52,3 +53,9 @@ yarn-error.log*
coverage/
*.lcov
.nyc_output

# Security Audit Results (Generated by CI/local testing)
audit-results*.json

# Security Audit Results (Generated by local testing)
audit-results*.json
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,28 @@ Framework examples follow a simpler workflow:

No copier tool is used - snippets are committed directly to this repository.

### Security Audits

Dependency security audits run automatically on PRs to `development`:

- **`audit-tanstack.yml`** — runs `npm audit` on TanStack app and Bluehawk dependencies
- **`audit-python-fastapi.yml`** — runs `pip-audit` on Python FastAPI dependencies

**To test locally:**

```bash
# npm (TanStack)
cd frameworks/javascript/tanstack/app
npm audit --audit-level=high

# pip (Python FastAPI)
cd mflix/server/python-fastapi
pip install pip-audit
pip-audit -r requirements.txt
```

If an audit fails on your PR, check the workflow summary for details on which packages need updating.

### MFlix Release Process

When you merge a release PR from `development` to `main`, the copier tool
Expand Down
Loading
Loading