Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
386
.gitea/workflows/sast-scan.yml
Normal file
386
.gitea/workflows/sast-scan.yml
Normal file
@@ -0,0 +1,386 @@
|
||||
# .gitea/workflows/sast-scan.yml
|
||||
# Static Application Security Testing (SAST) Workflow
|
||||
# Sprint: CI/CD Enhancement - Security Scanning (Tier 2)
|
||||
#
|
||||
# Purpose: Detect security vulnerabilities in source code through static analysis
|
||||
# - Code injection vulnerabilities
|
||||
# - Authentication/authorization issues
|
||||
# - Cryptographic weaknesses
|
||||
# - Data exposure risks
|
||||
# - OWASP Top 10 detection
|
||||
#
|
||||
# Supported Languages: C#/.NET, JavaScript/TypeScript, Python, YAML, Dockerfile
|
||||
#
|
||||
# PLACEHOLDER: Choose your SAST scanner implementation below
|
||||
# Options:
|
||||
# 1. Semgrep - Fast, open-source, good .NET support
|
||||
# 2. CodeQL - GitHub's analysis engine
|
||||
# 3. SonarQube - Enterprise-grade with dashboards
|
||||
# 4. Snyk Code - Commercial with good accuracy
|
||||
|
||||
name: SAST Scanning
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '*.csproj'
|
||||
- '*.cs'
|
||||
- '*.ts'
|
||||
- '*.js'
|
||||
- '*.py'
|
||||
- 'Dockerfile*'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '*.csproj'
|
||||
- '*.cs'
|
||||
- '*.ts'
|
||||
- '*.js'
|
||||
- '*.py'
|
||||
- 'Dockerfile*'
|
||||
schedule:
|
||||
- cron: '30 3 * * 1' # Weekly on Monday at 3:30 AM UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
scan_level:
|
||||
description: 'Scan thoroughness level'
|
||||
type: choice
|
||||
options:
|
||||
- quick
|
||||
- standard
|
||||
- comprehensive
|
||||
default: standard
|
||||
fail_on_findings:
|
||||
description: 'Fail workflow on findings'
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
env:
|
||||
DOTNET_VERSION: '10.0.100'
|
||||
TZ: UTC
|
||||
|
||||
jobs:
|
||||
# ===========================================================================
|
||||
# PLACEHOLDER SAST IMPLEMENTATION
|
||||
# ===========================================================================
|
||||
#
|
||||
# IMPORTANT: Configure your preferred SAST tool by uncommenting ONE of the
|
||||
# implementation options below. Each option includes the necessary steps
|
||||
# and configuration for that specific tool.
|
||||
#
|
||||
# ===========================================================================
|
||||
|
||||
sast-scan:
|
||||
name: SAST Analysis
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# =========================================================================
|
||||
# PLACEHOLDER: Uncomment your preferred SAST tool configuration
|
||||
# =========================================================================
|
||||
|
||||
- name: SAST Scan Placeholder
|
||||
run: |
|
||||
echo "::notice::SAST scanning placeholder - configure your scanner below"
|
||||
echo ""
|
||||
echo "Available SAST options:"
|
||||
echo ""
|
||||
echo "1. SEMGREP (Recommended for open-source)"
|
||||
echo " Uncomment the Semgrep section below"
|
||||
echo " - Fast, accurate, good .NET support"
|
||||
echo " - Free for open-source projects"
|
||||
echo ""
|
||||
echo "2. CODEQL (GitHub native)"
|
||||
echo " Uncomment the CodeQL section below"
|
||||
echo " - Deep analysis capabilities"
|
||||
echo " - Native GitHub integration"
|
||||
echo ""
|
||||
echo "3. SONARQUBE (Enterprise)"
|
||||
echo " Uncomment the SonarQube section below"
|
||||
echo " - Comprehensive dashboards"
|
||||
echo " - Technical debt tracking"
|
||||
echo ""
|
||||
echo "4. SNYK CODE (Commercial)"
|
||||
echo " Uncomment the Snyk section below"
|
||||
echo " - High accuracy"
|
||||
echo " - Good IDE integration"
|
||||
|
||||
# =========================================================================
|
||||
# OPTION 1: SEMGREP
|
||||
# =========================================================================
|
||||
# Uncomment the following section to use Semgrep:
|
||||
#
|
||||
# - name: Run Semgrep
|
||||
# uses: returntocorp/semgrep-action@v1
|
||||
# with:
|
||||
# config: >-
|
||||
# p/default
|
||||
# p/security-audit
|
||||
# p/owasp-top-ten
|
||||
# p/csharp
|
||||
# p/javascript
|
||||
# p/typescript
|
||||
# p/python
|
||||
# p/docker
|
||||
# env:
|
||||
# SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
|
||||
# =========================================================================
|
||||
# OPTION 2: CODEQL
|
||||
# =========================================================================
|
||||
# Uncomment the following section to use CodeQL:
|
||||
#
|
||||
# - name: Initialize CodeQL
|
||||
# uses: github/codeql-action/init@v3
|
||||
# with:
|
||||
# languages: csharp, javascript
|
||||
# queries: security-and-quality
|
||||
#
|
||||
# - name: Build for CodeQL
|
||||
# run: |
|
||||
# dotnet build src/StellaOps.sln --configuration Release
|
||||
#
|
||||
# - name: Perform CodeQL Analysis
|
||||
# uses: github/codeql-action/analyze@v3
|
||||
# with:
|
||||
# category: "/language:csharp"
|
||||
|
||||
# =========================================================================
|
||||
# OPTION 3: SONARQUBE
|
||||
# =========================================================================
|
||||
# Uncomment the following section to use SonarQube:
|
||||
#
|
||||
# - name: SonarQube Scan
|
||||
# uses: SonarSource/sonarqube-scan-action@master
|
||||
# env:
|
||||
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
# SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||
# with:
|
||||
# args: >
|
||||
# -Dsonar.projectKey=stellaops
|
||||
# -Dsonar.sources=src/
|
||||
# -Dsonar.exclusions=**/bin/**,**/obj/**,**/node_modules/**
|
||||
|
||||
# =========================================================================
|
||||
# OPTION 4: SNYK CODE
|
||||
# =========================================================================
|
||||
# Uncomment the following section to use Snyk Code:
|
||||
#
|
||||
# - name: Setup Snyk
|
||||
# uses: snyk/actions/setup@master
|
||||
#
|
||||
# - name: Snyk Code Test
|
||||
# run: snyk code test --sarif-file-output=snyk-code.sarif
|
||||
# env:
|
||||
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
# continue-on-error: true
|
||||
#
|
||||
# - name: Upload Snyk results
|
||||
# uses: github/codeql-action/upload-sarif@v3
|
||||
# with:
|
||||
# sarif_file: snyk-code.sarif
|
||||
|
||||
# ===========================================================================
|
||||
# .NET SECURITY ANALYSIS (built-in)
|
||||
# ===========================================================================
|
||||
|
||||
dotnet-security:
|
||||
name: .NET Security Analysis
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
include-prerelease: true
|
||||
|
||||
- name: Restore packages
|
||||
run: dotnet restore src/StellaOps.sln
|
||||
|
||||
- name: Run Security Code Analysis
|
||||
run: |
|
||||
# Enable nullable reference types warnings as errors for security
|
||||
dotnet build src/StellaOps.sln \
|
||||
--configuration Release \
|
||||
--no-restore \
|
||||
/p:TreatWarningsAsErrors=false \
|
||||
/p:EnableNETAnalyzers=true \
|
||||
/p:AnalysisLevel=latest \
|
||||
/warnaserror:CA2100,CA2109,CA2119,CA2153,CA2300,CA2301,CA2302,CA2305,CA2310,CA2311,CA2312,CA2315,CA2321,CA2322,CA2326,CA2327,CA2328,CA2329,CA2330,CA2350,CA2351,CA2352,CA2353,CA2354,CA2355,CA2356,CA2361,CA2362,CA3001,CA3002,CA3003,CA3004,CA3005,CA3006,CA3007,CA3008,CA3009,CA3010,CA3011,CA3012,CA3061,CA3075,CA3076,CA3077,CA3147,CA5350,CA5351,CA5358,CA5359,CA5360,CA5361,CA5362,CA5363,CA5364,CA5365,CA5366,CA5367,CA5368,CA5369,CA5370,CA5371,CA5372,CA5373,CA5374,CA5375,CA5376,CA5377,CA5378,CA5379,CA5380,CA5381,CA5382,CA5383,CA5384,CA5385,CA5386,CA5387,CA5388,CA5389,CA5390,CA5391,CA5392,CA5393,CA5394,CA5395,CA5396,CA5397,CA5398,CA5399,CA5400,CA5401,CA5402,CA5403 \
|
||||
2>&1 | tee build-security.log || true
|
||||
|
||||
- name: Parse security warnings
|
||||
run: |
|
||||
echo "### .NET Security Analysis" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Count security warnings
|
||||
SECURITY_WARNINGS=$(grep -E "warning CA[235][0-9]{3}" build-security.log | wc -l || echo "0")
|
||||
echo "- Security warnings found: $SECURITY_WARNINGS" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [[ $SECURITY_WARNINGS -gt 0 ]]; then
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "<details><summary>Security Warnings</summary>" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
grep -E "warning CA[235][0-9]{3}" build-security.log | head -50 >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Upload security log
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: sast-dotnet-security-log
|
||||
path: build-security.log
|
||||
retention-days: 14
|
||||
|
||||
# ===========================================================================
|
||||
# DEPENDENCY VULNERABILITY CHECK
|
||||
# ===========================================================================
|
||||
|
||||
dependency-check:
|
||||
name: Dependency Vulnerabilities
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
include-prerelease: true
|
||||
|
||||
- name: Run vulnerability audit
|
||||
run: |
|
||||
echo "### Dependency Vulnerability Audit" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Check for known vulnerabilities in NuGet packages
|
||||
dotnet list src/StellaOps.sln package --vulnerable --include-transitive 2>&1 | tee vuln-report.txt || true
|
||||
|
||||
# Parse results
|
||||
VULN_COUNT=$(grep -c "has the following vulnerable packages" vuln-report.txt || echo "0")
|
||||
|
||||
if [[ $VULN_COUNT -gt 0 ]]; then
|
||||
echo "::warning::Found $VULN_COUNT projects with vulnerable dependencies"
|
||||
echo "- Projects with vulnerabilities: $VULN_COUNT" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "<details><summary>Vulnerability Report</summary>" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
cat vuln-report.txt >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "</details>" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "No known vulnerabilities found in dependencies." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Upload vulnerability report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: sast-vulnerability-report
|
||||
path: vuln-report.txt
|
||||
retention-days: 14
|
||||
|
||||
# ===========================================================================
|
||||
# DOCKERFILE SECURITY LINTING
|
||||
# ===========================================================================
|
||||
|
||||
dockerfile-lint:
|
||||
name: Dockerfile Security
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Find Dockerfiles
|
||||
id: find
|
||||
run: |
|
||||
DOCKERFILES=$(find . -name "Dockerfile*" -type f ! -path "./node_modules/*" | jq -R -s -c 'split("\n") | map(select(length > 0))')
|
||||
COUNT=$(echo "$DOCKERFILES" | jq 'length')
|
||||
echo "files=$DOCKERFILES" >> $GITHUB_OUTPUT
|
||||
echo "count=$COUNT" >> $GITHUB_OUTPUT
|
||||
echo "Found $COUNT Dockerfiles"
|
||||
|
||||
- name: Install Hadolint
|
||||
if: steps.find.outputs.count != '0'
|
||||
run: |
|
||||
wget -qO hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64
|
||||
chmod +x hadolint
|
||||
sudo mv hadolint /usr/local/bin/
|
||||
|
||||
- name: Lint Dockerfiles
|
||||
if: steps.find.outputs.count != '0'
|
||||
run: |
|
||||
echo "### Dockerfile Security Lint" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
TOTAL_ISSUES=0
|
||||
|
||||
for dockerfile in $(echo '${{ steps.find.outputs.files }}' | jq -r '.[]'); do
|
||||
echo "Linting: $dockerfile"
|
||||
ISSUES=$(hadolint --format json "$dockerfile" 2>/dev/null || echo "[]")
|
||||
ISSUE_COUNT=$(echo "$ISSUES" | jq 'length')
|
||||
TOTAL_ISSUES=$((TOTAL_ISSUES + ISSUE_COUNT))
|
||||
|
||||
if [[ $ISSUE_COUNT -gt 0 ]]; then
|
||||
echo "- **$dockerfile**: $ISSUE_COUNT issues" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
done
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Total issues found: $TOTAL_ISSUES**" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [[ $TOTAL_ISSUES -gt 0 ]] && [[ "${{ github.event.inputs.fail_on_findings }}" == "true" ]]; then
|
||||
echo "::warning::Found $TOTAL_ISSUES Dockerfile security issues"
|
||||
fi
|
||||
|
||||
# ===========================================================================
|
||||
# SUMMARY
|
||||
# ===========================================================================
|
||||
|
||||
summary:
|
||||
name: SAST Summary
|
||||
runs-on: ubuntu-22.04
|
||||
needs: [sast-scan, dotnet-security, dependency-check, dockerfile-lint]
|
||||
if: always()
|
||||
steps:
|
||||
- name: Generate summary
|
||||
run: |
|
||||
echo "## SAST Scan Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| SAST Analysis | ${{ needs.sast-scan.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| .NET Security | ${{ needs.dotnet-security.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Dependency Check | ${{ needs.dependency-check.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Dockerfile Lint | ${{ needs.dockerfile-lint.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Check for failures
|
||||
if: |
|
||||
github.event.inputs.fail_on_findings == 'true' &&
|
||||
(needs.sast-scan.result == 'failure' ||
|
||||
needs.dotnet-security.result == 'failure' ||
|
||||
needs.dependency-check.result == 'failure')
|
||||
run: exit 1
|
||||
Reference in New Issue
Block a user