diff --git a/.github/workflows/horusec-security-scan.yml b/.github/workflows/horusec-security-scan.yml new file mode 100644 index 0000000..a92ccec --- /dev/null +++ b/.github/workflows/horusec-security-scan.yml @@ -0,0 +1,92 @@ +name: Horusec Security Scan + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: "0 0 * * 0" # Weekly at midnight on Sunday + +jobs: + horusec-security: + name: Horusec Security Scan + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # Cache Horusec to speed up subsequent runs + - name: Cache Horusec + uses: actions/cache@v3 + with: + path: ~/.horusec + key: ${{ runner.os }}-horusec-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-horusec- + + - name: Running Horusec Security Scan + id: horusec + uses: horuszup/horusec-action@v1.0.0 + with: + arguments: > + -p="./" + --config-file-path="./horusec-config.json" + --output-format="json" + --output="./horusec-report.json" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Upload security scan results as an artifact + - name: Upload Horusec Report + uses: actions/upload-artifact@v3 + if: always() + with: + name: horusec-report + path: horusec-report.json + retention-days: 7 + + # Analyze Elixir-specific vulnerabilities with Sobelow + - name: Set up Elixir + if: always() + uses: erlef/setup-beam@v1 + with: + elixir-version: "1.17.x" + otp-version: "26.x" + + - name: Cache Elixir deps + if: always() + uses: actions/cache@v3 + with: + path: | + deps + _build + key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} + restore-keys: | + ${{ runner.os }}-mix- + + - name: Install dependencies + if: always() + run: mix deps.get + + - name: Run Sobelow (Elixir-specific security scan) + if: always() + run: mix sobelow --format=json --out=sobelow-report.json --exit + + - name: Upload Sobelow Report + uses: actions/upload-artifact@v3 + if: always() + with: + name: sobelow-report + path: sobelow-report.json + retention-days: 7 + + # Optional: Fail the workflow if critical vulnerabilities are found + - name: Check for critical vulnerabilities + if: ${{ steps.horusec.outputs.exit-code != '0' }} + run: | + echo "Critical vulnerabilities found in the security scan!" + echo "Review the security reports in the workflow artifacts." + exit 1 diff --git a/horusec-config.json b/horusec-config.json new file mode 100644 index 0000000..12144cb --- /dev/null +++ b/horusec-config.json @@ -0,0 +1,137 @@ +{ + "horusecCliCertInsecureSkipVerify": false, + "horusecCliCertPath": "", + "horusecCliContainerBindProjectPath": "", + "horusecCliCustomImages": { + "c": "", + "csharp": "", + "elixir": "", + "generic": "", + "go": "", + "hcl": "", + "javascript": "", + "leaks": "", + "php": "", + "python": "", + "ruby": "", + "shell": "" + }, + "horusecCliCustomRulesPath": "", + "horusecCliDisableDocker": false, + "horusecCliEnableCommitAuthor": false, + "horusecCliEnableGitHistoryAnalysis": false, + "horusecCliEnableInformationSeverity": false, + "horusecCliEnableOwaspDependencyCheck": false, + "horusecCliEnableShellcheck": false, + "horusecCliFalsePositiveHashes": null, + "horusecCliFilesOrPathsToIgnore": [ + "*tmp*", + "**/.vscode/**" + ], + "horusecCliHeaders": {}, + "horusecCliHorusecApiUri": "http://0.0.0.0:8000", + "horusecCliJsonOutputFilepath": "", + "horusecCliLogFilePath": "/var/folders/jd/ht5fj9p500s446w5lvrbcjc00000gn/T/horusec-2025-06-15-17-12-14.log", + "horusecCliMonitorRetryInSeconds": 15, + "horusecCliPrintOutputType": "", + "horusecCliProjectPath": "/Users/graham/dev/aprs.me", + "horusecCliRepositoryAuthorization": "00000000-0000-0000-0000-000000000000", + "horusecCliRepositoryName": "aprs.me", + "horusecCliReturnErrorIfFoundVulnerability": false, + "horusecCliRiskAcceptHashes": null, + "horusecCliSeveritiesToIgnore": [ + "INFO" + ], + "horusecCliShowVulnerabilitiesTypes": [ + "Vulnerability" + ], + "horusecCliTimeoutInSecondsAnalysis": 600, + "horusecCliTimeoutInSecondsRequest": 300, + "horusecCliToolsConfig": { + "Bandit": { + "istoignore": false + }, + "Brakeman": { + "istoignore": false + }, + "BundlerAudit": { + "istoignore": false + }, + "Checkov": { + "istoignore": false + }, + "DotnetCli": { + "istoignore": false + }, + "Flawfinder": { + "istoignore": false + }, + "GitLeaks": { + "istoignore": false + }, + "GoSec": { + "istoignore": false + }, + "HorusecEngine": { + "istoignore": false + }, + "MixAudit": { + "istoignore": false + }, + "Nancy": { + "istoignore": false + }, + "NpmAudit": { + "istoignore": false + }, + "OwaspDependencyCheck": { + "istoignore": false + }, + "PhpCS": { + "istoignore": false + }, + "Safety": { + "istoignore": false + }, + "SecurityCodeScan": { + "istoignore": false + }, + "Semgrep": { + "istoignore": false + }, + "ShellCheck": { + "istoignore": false + }, + "Sobelow": { + "istoignore": false + }, + "TfSec": { + "istoignore": false + }, + "Trivy": { + "istoignore": false + }, + "YarnAudit": { + "istoignore": false + } + }, + "horusecCliWorkDir": { + "go": [], + "csharp": [], + "ruby": [], + "python": [], + "java": [], + "kotlin": [], + "javaScript": [], + "leaks": [], + "hcl": [], + "php": [], + "c": [], + "yaml": [], + "generic": [], + "elixir": [], + "shell": [], + "dart": [], + "nginx": [] + } +} \ No newline at end of file