Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
157 changes: 157 additions & 0 deletions .github/workflows/fuzz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
name: Fuzzing

on:
# Run weekly on Sunday at midnight UTC
schedule:
- cron: '0 0 * * 0'
# Allow manual triggering
workflow_dispatch:
inputs:
fuzz_target:
description: 'Fuzz target to run (or "all" for all targets)'
required: true
default: 'all'
type: choice
options:
- all
- rlp_decode
- rlp_roundtrip
- trie_operations
- transaction_decode
- block_decode
- block_header_decode
- precompile_all
- precompile_ecrecover
- precompile_modexp
- precompile_bn254
- precompile_bls12_381
duration:
description: 'Fuzzing duration per target (in seconds)'
required: true
default: '300'
type: string

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
CARGO_NET_RETRY: "10"

jobs:
fuzz:
name: Fuzz - ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- rlp_decode
- rlp_roundtrip
- trie_operations
- transaction_decode
- block_decode
- block_header_decode
- precompile_all
- precompile_ecrecover
- precompile_modexp
- precompile_bn254
- precompile_bls12_381
steps:
- name: Check if target should run
id: check
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
if [[ "${{ github.event.inputs.fuzz_target }}" == "all" ]] || [[ "${{ github.event.inputs.fuzz_target }}" == "${{ matrix.target }}" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
echo "duration=${{ github.event.inputs.duration }}" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi
else
# Scheduled run - run all targets for 5 minutes each
echo "run=true" >> "$GITHUB_OUTPUT"
echo "duration=300" >> "$GITHUB_OUTPUT"
fi

- name: Checkout sources
if: steps.check.outputs.run == 'true'
uses: actions/checkout@v4

- name: Free Disk Space
if: steps.check.outputs.run == 'true'
uses: ./.github/actions/free-disk

- name: Install Rust nightly
if: steps.check.outputs.run == 'true'
uses: dtolnay/rust-toolchain@nightly

- name: Add Rust Cache
if: steps.check.outputs.run == 'true'
uses: Swatinem/rust-cache@v2
with:
workspaces: fuzz -> target

- name: Install cargo-fuzz
if: steps.check.outputs.run == 'true'
run: cargo install cargo-fuzz --locked

- name: Download corpus (if exists)
if: steps.check.outputs.run == 'true'
uses: actions/download-artifact@v4
with:
name: fuzz-corpus-${{ matrix.target }}
path: fuzz/corpus/${{ matrix.target }}
continue-on-error: true

- name: Run fuzzer
if: steps.check.outputs.run == 'true'
working-directory: fuzz
run: |
cargo fuzz run ${{ matrix.target }} -- \
-max_total_time=${{ steps.check.outputs.duration }} \
-max_len=4096

- name: Upload corpus
if: steps.check.outputs.run == 'true' && always()
uses: actions/upload-artifact@v4
with:
name: fuzz-corpus-${{ matrix.target }}
path: fuzz/corpus/${{ matrix.target }}
retention-days: 30

- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-crashes-${{ matrix.target }}
path: fuzz/artifacts/${{ matrix.target }}
if-no-files-found: ignore

# Quick smoke test for PRs - just compile fuzz targets
fuzz-compile-check:
name: Fuzz Compile Check
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Free Disk Space
uses: ./.github/actions/free-disk

- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly

- name: Add Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: fuzz -> target

- name: Check fuzz targets compile
working-directory: fuzz
run: cargo check --all-targets
32 changes: 32 additions & 0 deletions .github/workflows/pr_dependency_review.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Dependency Review

on:
pull_request:
branches: ["main"]
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'

permissions:
contents: read
pull-requests: write

jobs:
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
# Fail on high severity vulnerabilities
fail-on-severity: high
# Also warn about moderate severity
warn-only: true
# Allow specific licenses
allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, Unlicense, Zlib, MPL-2.0
# Comment on PR with findings
comment-summary-in-pr: on-failure
44 changes: 44 additions & 0 deletions .github/workflows/pr_proptest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Property Tests

on:
pull_request:
branches: ["**"]
paths:
- 'crates/common/rlp/**'
- 'crates/common/trie/**'
- 'crates/common/types/**'

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
CARGO_NET_RETRY: "10"
# Run more proptest cases in CI
PROPTEST_CASES: "1000"

jobs:
proptest:
name: Property Tests
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Free Disk Space
uses: ./.github/actions/free-disk

- name: Setup Rust Environment
uses: ./.github/actions/setup-rust

- name: Run RLP property tests
run: |
cargo test -p ethrex-rlp --release -- proptests

- name: Run Trie property tests
run: |
cargo test -p ethrex-trie --release -- proptest
143 changes: 143 additions & 0 deletions .github/workflows/security.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Security

on:
push:
branches: ["main"]
pull_request:
branches: ["**"]
schedule:
# Run daily at 6 AM UTC
- cron: '0 6 * * *'

permissions:
contents: read
security-events: write

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
CARGO_NET_RETRY: "10"

jobs:
# Audit dependencies for known vulnerabilities
cargo-audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Install cargo-audit
run: cargo install cargo-audit --locked

- name: Run cargo audit
run: cargo audit --deny warnings

# Check dependencies against advisory database and license policies
cargo-deny:
name: Dependency Check
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Install cargo-deny
run: cargo install cargo-deny --locked

- name: Run cargo deny
run: cargo deny check

# Security-focused clippy lints
clippy-security:
name: Security Lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Free Disk Space
uses: ./.github/actions/free-disk

- name: Setup Rust Environment
uses: ./.github/actions/setup-rust
with:
components: clippy

- name: Run security-focused clippy lints
run: |
cargo clippy -- \
-D clippy::unwrap_used \
-D clippy::expect_used \
-D clippy::panic \
-D clippy::todo \
-D clippy::unimplemented \
-D clippy::unreachable \
-W clippy::integer_arithmetic \
-W clippy::arithmetic_side_effects \
-W clippy::cast_possible_truncation \
-W clippy::cast_sign_loss \
-W clippy::cast_possible_wrap \
-W clippy::indexing_slicing
continue-on-error: true # Report but don't fail initially

# Check for unsafe code usage
unsafe-audit:
name: Unsafe Code Audit
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Free Disk Space
uses: ./.github/actions/free-disk

- name: Setup Rust Environment
uses: ./.github/actions/setup-rust

- name: Install cargo-geiger
run: cargo install cargo-geiger --locked

- name: Run cargo geiger
run: cargo geiger --all-features --all-targets 2>&1 | tee unsafe-report.txt
continue-on-error: true

- name: Upload unsafe code report
uses: actions/upload-artifact@v4
with:
name: unsafe-code-report
path: unsafe-report.txt

# SARIF output for GitHub Security tab (on schedule only to avoid noise)
sarif-clippy:
name: SARIF Security Report
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event_name == 'push'
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Free Disk Space
uses: ./.github/actions/free-disk

- name: Setup Rust Environment
uses: ./.github/actions/setup-rust
with:
components: clippy

- name: Install clippy-sarif and sarif-fmt
run: |
cargo install clippy-sarif sarif-fmt --locked

- name: Run clippy with SARIF output
run: |
cargo clippy --message-format=json 2>&1 | clippy-sarif | tee clippy-results.sarif | sarif-fmt
continue-on-error: true

- name: Upload SARIF results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: clippy-results.sarif
wait-for-processing: true
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,10 @@ rocksdb = { version = "0.24.0", default-features = false, features = [
"lz4",
] }

# Testing dependencies
proptest = "1.5"
arbitrary = { version = "1", features = ["derive"] }
test-strategy = "0.4"

[workspace.lints.clippy]
redundant_clone = "warn"
Loading
Loading