{"id":44806590,"url":"https://github.com/7a6163/gem-audit","last_synced_at":"2026-04-01T23:38:39.834Z","repository":{"id":337811631,"uuid":"1155307403","full_name":"7a6163/gem-audit","owner":"7a6163","description":"Ultra-fast, standalone security auditor for Gemfile.lock — written in Rust","archived":false,"fork":false,"pushed_at":"2026-03-22T12:03:19.000Z","size":416,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-23T03:41:24.372Z","etag":null,"topics":["audit","bundler","cli","cve","gemfile","ruby","ruby-on-rails","rust","security","security-tools","vulnerability-scanner"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/7a6163.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-11T11:11:41.000Z","updated_at":"2026-03-19T03:53:18.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/7a6163/gem-audit","commit_stats":null,"previous_names":["7a6163/bundler-audit-rs","7a6163/gem-audit"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/7a6163/gem-audit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7a6163%2Fgem-audit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7a6163%2Fgem-audit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7a6163%2Fgem-audit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7a6163%2Fgem-audit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/7a6163","download_url":"https://codeload.github.com/7a6163/gem-audit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7a6163%2Fgem-audit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292994,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audit","bundler","cli","cve","gemfile","ruby","ruby-on-rails","rust","security","security-tools","vulnerability-scanner"],"created_at":"2026-02-16T15:00:45.697Z","updated_at":"2026-04-01T23:38:39.812Z","avatar_url":"https://github.com/7a6163.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gem-audit\n\n[![CI](https://github.com/7a6163/gem-audit/actions/workflows/ci.yml/badge.svg)](https://github.com/7a6163/gem-audit/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/7a6163/gem-audit/graph/badge.svg)](https://codecov.io/gh/7a6163/gem-audit)\n[![Crates.io](https://img.shields.io/crates/v/gem-audit)](https://crates.io/crates/gem-audit)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.md)\n\nUltra-fast, standalone security auditor for [Bundler] dependencies, written in Rust.\n\nA security auditor for `Gemfile.lock` inspired by [bundler-audit], compiled to a\nsingle static binary with zero runtime dependencies -- no Ruby, no Bundler, no\ngem install required.\n\n## Features\n\n* Checks for vulnerable versions of gems in `Gemfile.lock`.\n* Checks the Ruby interpreter version against known CVEs.\n* Checks for insecure gem sources (`http://` and `git://`).\n* Allows ignoring specific advisories via CLI flags or a configuration file.\n* Filters by severity threshold (`--severity`).\n* Warns when the advisory database is stale (`--max-db-age`).\n* Strict mode treats parse/load warnings as errors (`--strict`).\n* Semantic exit codes for CI/CD integration (0/1/2/3).\n* Prints advisory information (CVE, GHSA, CVSS criticality, solution).\n* Supports text and JSON output formats.\n* Downloads and updates the [ruby-advisory-db] automatically.\n* Does not require Ruby or Bundler to be installed.\n\n## Install\n\n### From source\n\n```\n$ cargo install --path .\n```\n\n### Build from source\n\n```\n$ git clone https://github.com/user/gem-audit.git\n$ cd gem-audit\n$ cargo build --release\n$ ./target/release/gem-audit --version\n```\n\n## Usage\n\nAudit a project's `Gemfile.lock`:\n\n```\n$ gem-audit\n        Name: activerecord\n     Version: 3.2.10\n         CVE: CVE-2015-7577\n        GHSA: GHSA-xrr6-3pc4-m447\n Criticality: Medium\n         URL: https://groups.google.com/forum/#!topic/rubyonrails-security/cawsWcQ6c8g\n       Title: Nested attributes rejection proc bypass in Active Record\n    Solution: upgrade to '\u003e= 5.0.0.beta1.1', '~\u003e 4.2.5, \u003e= 4.2.5.1', '~\u003e 4.1.14, \u003e= 4.1.14.1', '~\u003e 3.2.22.1'\n\nVulnerabilities found! (1 unpatched gem)\n```\n\nUpdate the [ruby-advisory-db] before checking:\n\n```\n$ gem-audit check --update\n```\n\nIgnore specific advisories:\n\n```\n$ gem-audit check --ignore CVE-2020-1234 GHSA-xxxx-yyyy-zzzz\n```\n\nAudit a specific directory:\n\n```\n$ gem-audit check /path/to/project\n```\n\nCheck a custom `Gemfile.lock` file:\n\n```\n$ gem-audit check --gemfile-lock Gemfile.custom.lock\n```\n\nOutput in JSON format:\n\n```\n$ gem-audit check --format json\n```\n\nOutput to a file:\n\n```\n$ gem-audit check --format json --output audit-results.json\n```\n\nOnly report high and critical vulnerabilities:\n\n```\n$ gem-audit check --severity high\n```\n\nWarn if the advisory database is older than 7 days:\n\n```\n$ gem-audit check --max-db-age 7\n```\n\nFail in CI if the database is stale:\n\n```\n$ gem-audit check --max-db-age 7 --fail-on-stale\n```\n\nTreat parse/load warnings as errors:\n\n```\n$ gem-audit check --strict\n```\n\nShow remediation suggestions (dry-run, no files modified):\n\n```\n$ gem-audit check --fix\n```\n\nIgnore all detected vulnerabilities (writes to `.gem-audit.yml`):\n\n```\n$ gem-audit check --write-ignore\n```\n\nUse in CI (always update the advisory database before checking):\n\n```\n$ gem-audit check --update\n```\n\nA minimal GitHub Actions example:\n\n```yaml\n- name: Audit gems\n  run: gem-audit check --update\n```\n\nFor stricter CI enforcement — fail if the database couldn't be updated or is stale:\n\n```yaml\n- name: Audit gems\n  run: gem-audit check --update --max-db-age 1 --fail-on-stale\n```\n\nTo use the Docker image in GitLab CI, use the CI cache to store the advisory\ndatabase in a writable directory. This avoids git locking issues that can occur\non container overlay filesystems:\n\n```yaml\naudit:\n  image:\n    name: ghcr.io/7a6163/gem-audit\n    entrypoint: [\"\"]\n  variables:\n    GEM_AUDIT_DB: \"$CI_PROJECT_DIR/.ruby-advisory-db\"\n  cache:\n    key: ruby-advisory-db\n    paths:\n      - .ruby-advisory-db/\n  script:\n    - gem-audit check --update\n```\n\nThe first run clones the advisory database into the cache. Subsequent runs\nrestore it from cache and fetch only the latest changes.\n\nThe Ruby interpreter version from the `RUBY VERSION` section is also checked:\n\n```\n$ gem-audit\n      Engine: ruby\n     Version: 2.6.0\n         CVE: CVE-2021-31810\n Criticality: Medium\n         URL: https://www.ruby-lang.org/en/news/2021/07/07/...\n       Title: Trusting FTP PASV responses vulnerability in Net::FTP\n    Solution: upgrade Ruby to '\u003e= 3.0.2', '~\u003e 2.7.4', '~\u003e 2.6.8'\n\nVulnerabilities found! (1 vulnerable Ruby version)\n```\n\n## Commands\n\n| Command    | Description                                              |\n|------------|----------------------------------------------------------|\n| `check`    | Check `Gemfile.lock` for insecure dependencies (default) |\n| `update`   | Update the ruby-advisory-db                              |\n| `download` | Download the ruby-advisory-db                            |\n| `stats`    | Print ruby-advisory-db statistics                        |\n| `version`  | Print the gem-audit version                              |\n\nRunning `gem-audit` with no subcommand is equivalent to `gem-audit check`.\n\n## Check Options\n\n| Flag                        | Description                                |\n|-----------------------------|--------------------------------------------|\n| `-q`, `--quiet`             | Suppress output                            |\n| `-v`, `--verbose`           | Show detailed advisory descriptions        |\n| `-i`, `--ignore \u003cIDS\u003e...`   | Advisory IDs to ignore                     |\n| `-u`, `--update`            | Update the advisory database before check  |\n| `-D`, `--database \u003cPATH\u003e`   | Path to the advisory database              |\n| `-F`, `--format \u003cFORMAT\u003e`   | Output format: `text` (default) or `json`  |\n| `-G`, `--gemfile-lock \u003cFILE\u003e` | Path to the Gemfile.lock file            |\n| `-c`, `--config \u003cFILE\u003e`     | Configuration file (default: `.gem-audit.yml`) |\n| `-o`, `--output \u003cFILE\u003e`     | Write output to a file instead of stdout   |\n| `-S`, `--severity \u003cLEVEL\u003e`  | Minimum severity: `none`, `low`, `medium`, `high`, `critical` |\n| `--max-db-age \u003cDAYS\u003e`       | Warn if the advisory database is older than DAYS days |\n| `--fail-on-stale`           | Exit with code 3 if the database is stale  |\n| `--strict`                  | Treat parse/load warnings as errors (exit code 2) |\n| `--fix`                     | Show remediation suggestions for vulnerable gems   |\n| `--write-ignore`            | Write all detected advisory IDs to the config ignore list |\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| `0`  | No vulnerabilities found |\n| `1`  | Vulnerabilities found |\n| `2`  | Tool error (missing files, parse failures, `--strict` violations) |\n| `3`  | Advisory database is stale (`--fail-on-stale`) |\n\n## Configuration File\n\ngem-audit supports a per-project configuration file (`.gem-audit.yml`):\n\n```yaml\n---\nignore:\n  - CVE-2020-1234\n  - GHSA-xxxx-yyyy-zzzz\nmax_db_age_days: 7\n```\n\n* `ignore:` \\[Array\\\u003cString\\\u003e\\] - Advisory IDs to ignore (CVE, GHSA, or OSVDB).\n* `max_db_age_days:` \\[Integer\\] - Warn if the database is older than this many days. CLI `--max-db-age` overrides this value.\n\nThe legacy `.bundler-audit.yml` file name is also supported for backward\ncompatibility.\n\nYou can specify a custom config file path:\n\n```\n$ gem-audit check --config custom-audit.yml\n```\n\nCLI `--ignore` flags take precedence over the configuration file.\n\n## GitHub Actions\n\nA dedicated [gem-audit-action] is available on the GitHub Marketplace:\n\n```yaml\n- uses: 7a6163/gem-audit-action@v1\n```\n\nOr use the binary directly in your workflow:\n\n### Basic check\n\n```yaml\nname: Security Audit\non: [push, pull_request]\njobs:\n  audit:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n      - uses: 7a6163/gem-audit-action@v1\n```\n\n### Severity threshold\n\nOnly fail on high and critical vulnerabilities:\n\n```yaml\n      - uses: 7a6163/gem-audit-action@v1\n        with:\n          severity: high\n```\n\n### Strict mode with fresh database\n\n```yaml\n      - uses: 7a6163/gem-audit-action@v1\n        with:\n          strict: true\n          max-db-age: 7\n          fail-on-stale: true\n```\n\n### JSON report as artifact\n\n```yaml\n      - uses: 7a6163/gem-audit-action@v1\n        with:\n          format: json\n          output: audit-report.json\n        continue-on-error: true\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: audit-report\n          path: audit-report.json\n```\n\n[gem-audit-action]: https://github.com/7a6163/gem-audit-action\n\n## Docker\n\nA Docker image is available for running gem-audit in any CI environment:\n\n```\n$ docker build -t gem-audit .\n$ docker run --rm -v $(pwd):/workspace gem-audit check\n```\n\nThe image uses `gcr.io/distroless/cc-debian13:debug` as the runtime base.\nThe advisory database is downloaded on first run and stored in `/db` inside\nthe container. Mount a volume or use a CI cache to persist it across runs.\n\n### CI Examples\n\n**GitLab CI:**\n\n```yaml\ngem-audit:\n  image: ghcr.io/7a6163/gem-audit:latest\n  script:\n    - gem-audit check\n```\n\n**CircleCI:**\n\n```yaml\njobs:\n  gem-audit:\n    docker:\n      - image: ghcr.io/7a6163/gem-audit:latest\n    steps:\n      - checkout\n      - run: gem-audit check\n```\n\n**Bitbucket Pipelines:**\n\n```yaml\npipelines:\n  default:\n    - step:\n        name: gem-audit\n        image: ghcr.io/7a6163/gem-audit:latest\n        script:\n          - gem-audit check\n```\n\n**Drone CI:**\n\n```yaml\nsteps:\n  - name: gem-audit\n    image: ghcr.io/7a6163/gem-audit:latest\n    commands:\n      - gem-audit check\n```\n\n**Azure Pipelines:**\n\n```yaml\njobs:\n  - job: gem_audit\n    container: ghcr.io/7a6163/gem-audit:latest\n    steps:\n      - checkout: self\n      - script: gem-audit check\n```\n\n## Performance\n\nBenchmarked with [hyperfine] on Apple M-series, comparing against Ruby bundler-audit 0.9.2:\n\n| Benchmark | gem-audit (Rust) | bundler-audit (Ruby) | Speedup |\n|-----------|-----------------|----------------------|---------|\n| check (unpatched gems) | 7.0 ms | 216.5 ms | **~31x** |\n| check (secure, no vulns) | 16.6 ms | 250.2 ms | **~15x** |\n| startup (`version`) | 4.6 ms | 188.4 ms | **~41x** |\n\nRun the benchmark yourself:\n\n```\n$ ./benchmarks/bench.sh\n```\n\n## Comparison with bundler-audit\n\ngem-audit is a Rust reimplementation inspired by [bundler-audit] v0.9.x.\nBoth use the same [ruby-advisory-db] and produce equivalent output.\n\n### Feature comparison\n\n| Feature | gem-audit | bundler-audit |\n|---------|-----------|---------------|\n| Language | Rust | Ruby |\n| Runtime dependencies | **None** (single static binary) | Ruby, Bundler, Git |\n| Advisory database | [ruby-advisory-db] | [ruby-advisory-db] |\n| Git implementation | [gix] (pure Rust) | System Git CLI |\n| Vulnerability check | Yes | Yes |\n| Ruby version check | Yes | No (see [ruby_audit]) |\n| Insecure source check | Yes | Yes |\n| Ignore advisories | `--ignore` + config file | `--ignore` + config file |\n| Output formats | Text, JSON | Text, JSON |\n| Output to file | `--output` | `--output` |\n| Severity filtering | `--severity` | No |\n| Stale DB warning | `--max-db-age` | No |\n| Fail on stale DB | `--fail-on-stale` | No |\n| Strict mode | `--strict` | No |\n| Exit codes | 0 / 1 / 2 / 3 (semantic) | 0 / 1 |\n| DB statistics | `gem-audit stats` | No |\n| Configuration file | `.gem-audit.yml` | `.bundler-audit.yml` |\n| Backward-compatible config | `.bundler-audit.yml` supported | — |\n| Rake integration | No | Yes |\n| GitHub Action | [gem-audit-action] | Community actions |\n| Performance | ~7–17 ms | ~190–250 ms |\n\n### Why choose gem-audit?\n\n* **Zero dependencies** -- no Ruby, Bundler, or Git required. Drop a single binary into any CI image.\n* **15-41x faster** -- finishes in milliseconds, ideal for pre-commit hooks and fast CI pipelines.\n* **Ruby version scanning** -- checks the interpreter version against CVEs, built-in (no extra gem like [ruby_audit] needed).\n* **Severity filtering** -- only fail on `high` or `critical` vulnerabilities with `--severity`.\n* **Database freshness** -- `--max-db-age` and `--fail-on-stale` ensure your advisory data is never outdated.\n* **Strict mode** -- treat parse/load warnings as errors for stricter CI policies.\n* **Richer exit codes** -- distinguish between vulnerabilities (1), tool errors (2), and stale database (3).\n\n### Why choose bundler-audit?\n\n* **Rake integration** -- useful if your build is driven by Rake tasks.\n* **Ruby ecosystem** -- installs via `gem install bundler-audit`, no extra toolchain needed if Ruby is already present.\n\n## Architecture\n\n```\nsrc/\n  version/            # RubyGems version parsing and comparison\n    gem_version.rs    # Gem::Version semantics (segments, ordering, bump)\n    requirement.rs    # Gem::Requirement with all 7 operators (=, !=, \u003e, \u003c, \u003e=, \u003c=, ~\u003e)\n  lockfile/           # Gemfile.lock parser\n    parser.rs         # State-machine parser with indentation tracking\n    ruby_version.rs   # Ruby interpreter version parser (engine + patchlevel stripping)\n  advisory/           # Advisory database\n    model.rs          # Advisory YAML deserialization, vulnerability checking, CVSS\n    database.rs       # Database clone/update via gix, advisory enumeration\n  scanner.rs          # Ties lockfile + database; source, spec \u0026 Ruby scanning\n  configuration.rs    # .gem-audit.yml loading and validation\n  format/             # Output formatters\n    text.rs           # Human-readable text with ANSI colors\n    json.rs           # JSON output with serde_json\n  main.rs             # CLI (clap)\n```\n\n## License\n\nMIT. See [LICENSE.md](LICENSE.md) for details.\n\n[Bundler]: https://bundler.io\n[bundler-audit]: https://github.com/rubysec/bundler-audit\n[ruby_audit]: https://github.com/civisanalytics/ruby_audit\n[ruby-advisory-db]: https://github.com/rubysec/ruby-advisory-db\n[gix]: https://github.com/Byron/gitoxide\n[hyperfine]: https://github.com/sharkdp/hyperfine\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7a6163%2Fgem-audit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F7a6163%2Fgem-audit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7a6163%2Fgem-audit/lists"}