From 64399966d394c4eacf5d67c89daaa5e5980dae3a Mon Sep 17 00:00:00 2001 From: Kanwalpreet Dhindsa Date: Thu, 17 Sep 2026 09:52:27 -0700 Subject: [PATCH] Add Socket Basics security scanning workflow Runs SAST through OpenGrep, secret scanning through TruffleHog, and Dockerfile misconfiguration scanning through Trivy, submitting results to Socket.dev. .github/workflows/socket-basics.yml scheduled weekly + manual dispatch .socket-basics.json scanner configuration .semgrepignore SAST path exclusions Separate from socket-scan.yml, which covers dependency CVEs and Tier 1 reachability. Co-Authored-By: Claude Opus 5 --- .github/workflows/socket-basics.yml | 59 ++++++++++++++ .semgrepignore | 114 ++++++++++++++++++++++++++++ .socket-basics.json | 14 ++++ 3 files changed, 187 insertions(+) create mode 100644 .github/workflows/socket-basics.yml create mode 100644 .semgrepignore create mode 100644 .socket-basics.json diff --git a/.github/workflows/socket-basics.yml b/.github/workflows/socket-basics.yml new file mode 100644 index 0000000000..825d0e7494 --- /dev/null +++ b/.github/workflows/socket-basics.yml @@ -0,0 +1,59 @@ +# Socket Basics security scan for stellar-cli. +# Upstream: https://github.com/SocketDev/socket-basics +# Scanner settings live in .socket-basics.json; SAST path exclusions live in +# .semgrepignore. +# +# This workflow does SAST through OpenGrep, secret scanning through TruffleHog, +# Dockerfile misconfiguration scanning through Trivy, and submits results to +# Socket.dev +# +# Schedule: Saturday 14:26 UTC. socket-scan.yml occupies minutes +# :00 :12 :24 :36 :48 of every hour, so this repo's slot avoids those. + +name: Socket Basics security scan + +on: + workflow_dispatch: + schedule: + - cron: "26 14 * * 6" + +permissions: + contents: read + +jobs: + socket-basics: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Run Socket Basics + env: + SOCKET_SECURITY_API_TOKEN: ${{ secrets.SOCKET_SECURITY_API_TOKEN }} + SOCKET_ORG: stellar + run: | + set +e + docker run --rm \ + -v "$PWD:/github/workspace" \ + -w /github/workspace \ + -e SOCKET_SECURITY_API_TOKEN \ + -e SOCKET_ORG \ + -e GITHUB_REPOSITORY \ + -e GITHUB_REF_NAME \ + -e GITHUB_SHA \ + ghcr.io/socketdev/socket-basics@sha256:d463bae84f21d0240d5e197acb81e95144a966a20ab7cd05cca3a70e1796a4bb \ + --config .socket-basics.json 2>&1 | tee /tmp/socket-basics.log + rc=${PIPESTATUS[0]} + + # socket-basics exits non-zero merely BECAUSE high/critical findings + # exist, so the exit code is not a health signal. "Scan completed!" is. + # Findings raise a warning annotation; only a broken scan fails the job. + if grep -q "Scan completed!" /tmp/socket-basics.log; then + hc=$(grep -oE "Found [0-9]+ high/critical" /tmp/socket-basics.log \ + | grep -oE "[0-9]+" | head -1) + if [ -n "$hc" ] && [ "$hc" -gt 0 ]; then + echo "::warning::Socket Basics found $hc high/critical finding(s)" + fi + exit 0 + fi + echo "::error::Socket Basics did not complete (docker exit $rc)" + exit "${rc:-1}" diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 0000000000..7f9a3d96d8 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,114 @@ +# Paths excluded from SAST scanning (Socket Basics / OpenGrep). +# +# This file replaces built-in file ignore list for scanning, required to make +# the scan more accurate. + +# --- third-party / generated --- +.git/ +node_modules/ +vendor/ +third_party/ +thirdparty/ +.devcontainer/ +dist/ +build/ +target/ +.venv/ +venv/ +__pycache__/ +.yarn/ +generated/ +*.min.js + +# --- test / example / mock code --- +__fixtures__/ +__mocks__/ +__snapshots__/ +__tests__/ +acceptance-test/ +acceptance-tests/ +acceptance_test/ +acceptance_tests/ +benches/ +browser-test/ +browser-tests/ +browser_test/ +browser_tests/ +e2e/ +e2e-test/ +e2e-tests/ +e2e_test/ +e2e_tests/ +example/ +examples/ +fixtures/ +functional-test/ +functional-tests/ +functional_test/ +functional_tests/ +integration-test/ +integration-tests/ +integration_test/ +integration_tests/ +integrationtest/ +integrationtests/ +mock/ +mock-dapp/ +mocks/ +perf-test/ +perf-tests/ +perf_test/ +perf_tests/ +performance-test/ +performance-tests/ +performance_test/ +performance_tests/ +regression-test/ +regression-tests/ +regression_test/ +regression_tests/ +smoke-test/ +smoke-tests/ +smoke_test/ +smoke_tests/ +spec/ +specs/ +test/ +test-data/ +test-fixtures/ +testFixtures/ +testdata/ +testfixtures/ +tests/ +unit-test/ +unit-tests/ +unit_test/ +unit_tests/ +*.test.js +*.test.jsx +*.test.ts +*.test.tsx +*.test.mjs +*.spec.js +*.spec.jsx +*.spec.ts +*.spec.tsx +*_test.go +*_test.py +*_test.rb +*_test.exs +test_*.py +*Test.java +*Tests.java +*Test.kt +*Tests.kt +*Test.scala +*Test.cs +*Tests.cs +tests.rs +test.rs + +# --- repo-specific third-party (PER_REPO_VENDORED + +# git submodules); the generic patterns above cannot know these --- +soroban-test/ +ts-tests/ diff --git a/.socket-basics.json b/.socket-basics.json new file mode 100644 index 0000000000..6211d6de39 --- /dev/null +++ b/.socket-basics.json @@ -0,0 +1,14 @@ +{ + "workspace": ".", + "javascript_sast_enabled": true, + "ruby_sast_enabled": true, + "rust_sast_enabled": true, + "javascript_disabled_rules": "js-unhandled-promise-rejection,js-sensitive-data-in-logs,js-express-async-no-error-handler,js-error-stack-exposed", + "rust_disabled_rules": "rust-sql-injection,rust-unsafe-usage,rust-panic-in-production,rust-memory-safety,rust-env-injection,rust-path-traversal,rust-serde-security,rust-integer-overflow,rust-command-injection", + "sast_ignore_overrides": "rust-hardcoded-secrets:cmd/crates/stellar-ledger/src/lib.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/container/shared.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/contract/upload.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/keys/add.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/keys/fund.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/keys/public_key.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/message/sign.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/message/verify.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/commands/tx/new/clawback_claimable_balance.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/config/address.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/config/key.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/config/locator.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/config/secret.rs,rust-hardcoded-secrets:cmd/soroban-cli/src/signer/mod.rs", + "secret_scanning_enabled": true, + "console_tabular_enabled": true, + "socket_tier_1_enabled": false, + "trivy_vuln_enabled": false, + "trufflehog_exclude_dir": "node_modules,dist,build,vendor,target,.git,__fixtures__,__mocks__,__snapshots__,__tests__,acceptance-test,acceptance-tests,acceptance_test,acceptance_tests,benches,browser-test,browser-tests,browser_test,browser_tests,e2e,e2e-test,e2e-tests,e2e_test,e2e_tests,example,examples,fixtures,functional-test,functional-tests,functional_test,functional_tests,integration-test,integration-tests,integration_test,integration_tests,integrationtest,integrationtests,mock,mock-dapp,mocks,perf-test,perf-tests,perf_test,perf_tests,performance-test,performance-tests,performance_test,performance_tests,regression-test,regression-tests,regression_test,regression_tests,smoke-test,smoke-tests,smoke_test,smoke_tests,spec,specs,test,test-data,test-fixtures,testFixtures,testdata,testfixtures,tests,unit-test,unit-tests,unit_test,unit_tests,*.test.js,*.test.jsx,*.test.ts,*.test.tsx,*.test.mjs,*.spec.js,*.spec.jsx,*.spec.ts,*.spec.tsx,*_test.go,*_test.py,*_test.rb,*_test.exs,test_*.py,*Test.java,*Tests.java,*Test.kt,*Tests.kt,*Test.scala,*Test.cs,*Tests.cs,tests.rs,test.rs,yarn.lock,package-lock.json,pnpm-lock.yaml,Cargo.lock,go.sum,poetry.lock,Gemfile.lock,composer.lock,soroban-test,ts-tests" +}