CRITICAL fixes: - Race condition (TOCTOU) in payout/refund with SELECT FOR UPDATE (CRITICAL-001/002) - IDOR on analytics endpoint — ownership check enforced (CRITICAL-003) - CSWSH on all WebSocket endpoints — origin whitelist (CRITICAL-004) - Mass assignment on user self-update — strip privileged fields (CRITICAL-005) HIGH fixes: - Path traversal in marketplace upload — UUID filenames (HIGH-001) - IP spoofing — use Gin trusted proxy c.ClientIP() (HIGH-002) - Popularity metrics (followers, likes) set to json:"-" (HIGH-003) - bcrypt cost hardened to 12 everywhere (HIGH-004) - Refresh token lock made mandatory (HIGH-005) - Stream token replay prevention with access_count (HIGH-006) - Subscription trial race condition fixed (HIGH-007) - License download expiration check (HIGH-008) - Webhook amount validation (HIGH-009) - pprof endpoint removed from production (HIGH-010) MEDIUM fixes: - WebSocket message size limit 64KB (MEDIUM-010) - HSTS header in nginx production (MEDIUM-001) - CORS origin restricted in nginx-rtmp (MEDIUM-002) - Docker alpine pinned to 3.21 (MEDIUM-003/004) - Redis authentication enforced (MEDIUM-005) - GDPR account deletion expanded (MEDIUM-006) - .gitignore hardened (MEDIUM-007) LOW/INFO fixes: - GitHub Actions SHA pinning on all workflows (LOW-001) - .env.example security documentation (INFO-001) - Production CORS set to HTTPS (LOW-002) All tests pass. Go and Rust compile clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.7 KiB
YAML
84 lines
2.7 KiB
YAML
name: Container Image Scan
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'veza-backend-api/Dockerfile*'
|
|
- 'apps/web/Dockerfile*'
|
|
- 'veza-stream-server/Dockerfile*'
|
|
pull_request:
|
|
branches: [main]
|
|
paths:
|
|
- 'veza-backend-api/Dockerfile*'
|
|
- 'apps/web/Dockerfile*'
|
|
- 'veza-stream-server/Dockerfile*'
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
scan-backend:
|
|
name: Scan Backend Image
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Build backend image
|
|
run: docker build -t veza-backend:scan -f veza-backend-api/Dockerfile.production veza-backend-api/
|
|
|
|
- name: Run Trivy vulnerability scanner
|
|
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 # v0.28.0
|
|
with:
|
|
image-ref: 'veza-backend:scan'
|
|
format: 'table'
|
|
exit-code: '1'
|
|
severity: 'CRITICAL,HIGH'
|
|
ignore-unfixed: true
|
|
|
|
scan-stream-server:
|
|
name: Scan Stream Server Image
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Build stream server image
|
|
run: docker build -t veza-stream:scan -f veza-stream-server/Dockerfile .
|
|
|
|
- name: Run Trivy vulnerability scanner
|
|
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 # v0.28.0
|
|
with:
|
|
image-ref: 'veza-stream:scan'
|
|
format: 'table'
|
|
exit-code: '1'
|
|
severity: 'CRITICAL,HIGH'
|
|
ignore-unfixed: true
|
|
|
|
scan-frontend:
|
|
name: Scan Frontend Image
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
|
|
- name: Check if frontend Dockerfile exists
|
|
id: check
|
|
run: |
|
|
if [ -f "apps/web/Dockerfile" ] || [ -f "apps/web/Dockerfile.production" ]; then
|
|
echo "exists=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "exists=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Build frontend image
|
|
if: steps.check.outputs.exists == 'true'
|
|
run: |
|
|
DOCKERFILE=$([ -f "apps/web/Dockerfile.production" ] && echo "apps/web/Dockerfile.production" || echo "apps/web/Dockerfile")
|
|
docker build -t veza-frontend:scan -f "$DOCKERFILE" apps/web/
|
|
|
|
- name: Run Trivy vulnerability scanner
|
|
if: steps.check.outputs.exists == 'true'
|
|
uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 # v0.28.0
|
|
with:
|
|
image-ref: 'veza-frontend:scan'
|
|
format: 'table'
|
|
exit-code: '1'
|
|
severity: 'CRITICAL,HIGH'
|
|
ignore-unfixed: true
|