bundler-trivy 0.1.2 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +20 -20
- data/lib/bundler/trivy/config.rb +12 -9
- data/lib/bundler/trivy/plugin.rb +7 -3
- data/lib/bundler/trivy/reporter.rb +10 -3
- data/lib/bundler/trivy/scanner.rb +1 -1
- data/lib/bundler/trivy/version.rb +1 -1
- data/lib/bundler/trivy/vulnerability.rb +25 -3
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a7b59afe9e3d14eaedb5644c7c421ac940519940001ac27fc7bdbcba8c9e9f78
|
|
4
|
+
data.tar.gz: 95b5980cdd1bd8f25e166444e29d0907d05dff6d9dfaf37ac3a4969f6dd5ecd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 036bf8d9aedd742df8adec69f21f4c27412d7b705ff056c783248a90aae823827216efebafc854eea4bac01cb3ee80e6e2d577686c5f74da80aacb6b2c75b875
|
|
7
|
+
data.tar.gz: 35c039953350c276732df80b6934f0d079dd33543b067832c8ebe4e16fd4f63fddf7100a715e56243f7a63f5a97badfd9f56c3f0befb3cf4692fa1b27bfbcfd9
|
data/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A Bundler plugin that automatically integrates [Trivy](https://trivy.dev/) secur
|
|
|
12
12
|
- **CVE Ignore List**: Temporary ignore vulnerabilities with expiration dates
|
|
13
13
|
- **Multiple Output Formats**: Terminal (default), JSON, and compact modes
|
|
14
14
|
- **Detailed Reporting**: Clear vulnerability summaries with fix recommendations
|
|
15
|
-
- **Zero Dependencies**: Lightweight plugin with minimal runtime dependencies
|
|
15
|
+
- **Zero Gem Dependencies**: Lightweight plugin with minimal runtime dependencies - none besides other than trivy.
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
@@ -39,21 +39,21 @@ sudo apt-get install trivy
|
|
|
39
39
|
|
|
40
40
|
**From source** (currently):
|
|
41
41
|
```bash
|
|
42
|
-
gem build
|
|
43
|
-
bundle plugin install
|
|
42
|
+
gem build bunder-trivy.gemspec
|
|
43
|
+
bundle plugin install bunder-trivy --source .
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
**Coming soon - from RubyGems**:
|
|
47
47
|
```bash
|
|
48
|
-
gem install
|
|
49
|
-
bundle plugin install
|
|
48
|
+
gem install bunder-trivy
|
|
49
|
+
bundle plugin install bunder-trivy
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
### 3. Verify Installation
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
bundle plugin list
|
|
56
|
-
# Should show:
|
|
56
|
+
# Should show: bunder-trivy
|
|
57
57
|
|
|
58
58
|
trivy --version
|
|
59
59
|
# Should show: Version: 0.x.x or later
|
|
@@ -264,8 +264,8 @@ jobs:
|
|
|
264
264
|
|
|
265
265
|
- name: Install Plugin
|
|
266
266
|
run: |
|
|
267
|
-
gem build
|
|
268
|
-
bundle plugin install
|
|
267
|
+
gem build bunder-trivy.gemspec
|
|
268
|
+
bundle plugin install bunder-trivy --source .
|
|
269
269
|
|
|
270
270
|
- name: Install Dependencies with Security Scan
|
|
271
271
|
run: bundle install
|
|
@@ -282,8 +282,8 @@ security_scan:
|
|
|
282
282
|
- wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add -
|
|
283
283
|
- echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | tee -a /etc/apt/sources.list.d/trivy.list
|
|
284
284
|
- apt-get update && apt-get install -y trivy
|
|
285
|
-
- gem build
|
|
286
|
-
- bundle plugin install
|
|
285
|
+
- gem build bunder-trivy.gemspec
|
|
286
|
+
- bundle plugin install bunder-trivy --source .
|
|
287
287
|
script:
|
|
288
288
|
- bundle install
|
|
289
289
|
allow_failure: false
|
|
@@ -309,13 +309,13 @@ BUNDLER_TRIVY_FAIL_ON_HIGH=true bundle install
|
|
|
309
309
|
**Check plugin is installed**:
|
|
310
310
|
```bash
|
|
311
311
|
bundle plugin list
|
|
312
|
-
# Should show
|
|
312
|
+
# Should show bunder-trivy
|
|
313
313
|
```
|
|
314
314
|
|
|
315
315
|
**Reinstall if needed**:
|
|
316
316
|
```bash
|
|
317
|
-
bundle plugin uninstall
|
|
318
|
-
bundle plugin install
|
|
317
|
+
bundle plugin uninstall bunder-trivy
|
|
318
|
+
bundle plugin install bunder-trivy --source .
|
|
319
319
|
```
|
|
320
320
|
|
|
321
321
|
### Trivy not found
|
|
@@ -378,8 +378,8 @@ chmod +x $(which trivy)
|
|
|
378
378
|
### Setup
|
|
379
379
|
|
|
380
380
|
```bash
|
|
381
|
-
git clone https://github.com/durableprogramming/
|
|
382
|
-
cd
|
|
381
|
+
git clone https://github.com/durableprogramming/bunder-trivy.git
|
|
382
|
+
cd bunder-trivy
|
|
383
383
|
bundle install
|
|
384
384
|
```
|
|
385
385
|
|
|
@@ -410,12 +410,12 @@ bundle exec rubocop -a
|
|
|
410
410
|
|
|
411
411
|
```bash
|
|
412
412
|
# Build gem
|
|
413
|
-
gem build
|
|
413
|
+
gem build bunder-trivy.gemspec
|
|
414
414
|
|
|
415
415
|
# Install in test project
|
|
416
416
|
cd /path/to/test/project
|
|
417
|
-
bundle plugin uninstall
|
|
418
|
-
bundle plugin install
|
|
417
|
+
bundle plugin uninstall bunder-trivy || true
|
|
418
|
+
bundle plugin install bunder-trivy --source /path/to/plugin
|
|
419
419
|
|
|
420
420
|
# Test
|
|
421
421
|
bundle install
|
|
@@ -465,8 +465,8 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
465
465
|
|
|
466
466
|
## Support
|
|
467
467
|
|
|
468
|
-
- **Documentation**: [GitHub README](https://github.com/durableprogramming/
|
|
469
|
-
- **Issues**: [GitHub Issues](https://github.com/durableprogramming/
|
|
468
|
+
- **Documentation**: [GitHub README](https://github.com/durableprogramming/bunder-trivy)
|
|
469
|
+
- **Issues**: [GitHub Issues](https://github.com/durableprogramming/bunder-trivy/issues)
|
|
470
470
|
- **Email**: commercial@durableprogramming.com
|
|
471
471
|
|
|
472
472
|
## Credits
|
data/lib/bundler/trivy/config.rb
CHANGED
|
@@ -74,7 +74,7 @@ module Bundler
|
|
|
74
74
|
# config.fail_on_critical? # => true
|
|
75
75
|
def fail_on_critical?
|
|
76
76
|
env_bool("BUNDLER_TRIVY_FAIL_ON_CRITICAL",
|
|
77
|
-
|
|
77
|
+
file_value(%w[fail_on critical], ci_environment?))
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
# Determines if the plugin should exit with error on HIGH severity vulnerabilities.
|
|
@@ -86,7 +86,7 @@ module Bundler
|
|
|
86
86
|
# config.fail_on_high? # => true
|
|
87
87
|
def fail_on_high?
|
|
88
88
|
env_bool("BUNDLER_TRIVY_FAIL_ON_HIGH",
|
|
89
|
-
|
|
89
|
+
file_value(%w[fail_on high], false))
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
# Determines if the plugin should exit with error on ANY vulnerabilities.
|
|
@@ -111,7 +111,7 @@ module Bundler
|
|
|
111
111
|
# @return [Boolean] true if compact output is enabled
|
|
112
112
|
def compact_output?
|
|
113
113
|
env_bool("BUNDLER_TRIVY_COMPACT",
|
|
114
|
-
|
|
114
|
+
file_value(%w[output compact], ci_environment?))
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
# Determines if output should be in JSON format.
|
|
@@ -160,7 +160,7 @@ module Bundler
|
|
|
160
160
|
# config.trivy_timeout # => 300
|
|
161
161
|
def trivy_timeout
|
|
162
162
|
ENV.fetch("BUNDLER_TRIVY_TIMEOUT",
|
|
163
|
-
|
|
163
|
+
file_value(%w[scanning timeout], 120)).to_i
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
# Returns the list of ignored CVEs from configuration.
|
|
@@ -238,7 +238,8 @@ module Bundler
|
|
|
238
238
|
ignored_cves.each do |ignore|
|
|
239
239
|
if ignore["expires"]
|
|
240
240
|
begin
|
|
241
|
-
Date
|
|
241
|
+
# Handle both string and Date objects
|
|
242
|
+
ignore["expires"].is_a?(Date) ? ignore["expires"] : Date.parse(ignore["expires"].to_s)
|
|
242
243
|
rescue ArgumentError
|
|
243
244
|
errors << "Invalid expiration date for #{ignore["id"]}: #{ignore["expires"]}"
|
|
244
245
|
end
|
|
@@ -284,8 +285,8 @@ module Bundler
|
|
|
284
285
|
end
|
|
285
286
|
|
|
286
287
|
config
|
|
287
|
-
rescue
|
|
288
|
-
Bundler.ui.warn "Failed to load config: #{e.message}"
|
|
288
|
+
rescue => e
|
|
289
|
+
Bundler.ui.warn "Failed to load config (#{config_path}): #{e.message}"
|
|
289
290
|
{}
|
|
290
291
|
end
|
|
291
292
|
|
|
@@ -306,14 +307,16 @@ module Bundler
|
|
|
306
307
|
|
|
307
308
|
def deep_merge(hash1, hash2)
|
|
308
309
|
hash1.merge(hash2) do |_, v1, v2|
|
|
309
|
-
v1.is_a?(Hash) && v2.is_a?(Hash) ? deep_merge(v1, v2) : v2
|
|
310
|
+
(v1.is_a?(Hash) && v2.is_a?(Hash)) ? deep_merge(v1, v2) : v2
|
|
310
311
|
end
|
|
311
312
|
end
|
|
312
313
|
|
|
313
314
|
def expired?(ignore_entry)
|
|
314
315
|
return false unless ignore_entry["expires"]
|
|
315
316
|
|
|
316
|
-
|
|
317
|
+
# Handle both string and Date objects
|
|
318
|
+
expires = ignore_entry["expires"]
|
|
319
|
+
expiration_date = expires.is_a?(Date) ? expires : Date.parse(expires.to_s)
|
|
317
320
|
Date.today > expiration_date
|
|
318
321
|
rescue ArgumentError
|
|
319
322
|
# Handle invalid date format, treat as not expired to be safe
|
data/lib/bundler/trivy/plugin.rb
CHANGED
|
@@ -49,8 +49,12 @@ module Bundler
|
|
|
49
49
|
|
|
50
50
|
# Check if Trivy binary is available in PATH
|
|
51
51
|
unless scanner.trivy_available?
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
begin
|
|
53
|
+
Bundler.ui.warn "Trivy not found, skipping scan"
|
|
54
|
+
Bundler.ui.info "Install: https://trivy.dev/docs/getting-started/installation/"
|
|
55
|
+
rescue
|
|
56
|
+
# Ignore UI errors
|
|
57
|
+
end
|
|
54
58
|
return
|
|
55
59
|
end
|
|
56
60
|
|
|
@@ -64,7 +68,7 @@ module Bundler
|
|
|
64
68
|
|
|
65
69
|
# Exit with error code if vulnerabilities exceed configured thresholds
|
|
66
70
|
handle_exit_code(results, config)
|
|
67
|
-
rescue
|
|
71
|
+
rescue => e
|
|
68
72
|
Bundler.ui.warn "Trivy scan failed: #{e.message}"
|
|
69
73
|
Bundler.ui.debug e.backtrace.join("\n") if ENV["DEBUG"]
|
|
70
74
|
end
|
|
@@ -124,8 +124,15 @@ module Bundler
|
|
|
124
124
|
puts
|
|
125
125
|
|
|
126
126
|
fixable.group_by(&:package_name).each do |pkg, vulns|
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
# Get all fixed versions from all vulnerabilities for this package
|
|
128
|
+
all_versions = vulns.flat_map(&:fixed_versions).compact.uniq
|
|
129
|
+
# Find the maximum version that fixes all vulns (safest upgrade path)
|
|
130
|
+
recommended_version = all_versions.max_by { |v| Gem::Version.new(v) } if all_versions.any?
|
|
131
|
+
if recommended_version
|
|
132
|
+
puts " Update #{pkg} to #{recommended_version}: bundle update #{pkg}"
|
|
133
|
+
else
|
|
134
|
+
puts " Update #{pkg}: bundle update #{pkg}"
|
|
135
|
+
end
|
|
129
136
|
end
|
|
130
137
|
|
|
131
138
|
puts
|
|
@@ -164,7 +171,7 @@ module Bundler
|
|
|
164
171
|
end
|
|
165
172
|
|
|
166
173
|
def severity_order(severity)
|
|
167
|
-
{
|
|
174
|
+
{"CRITICAL" => 0, "HIGH" => 1, "MEDIUM" => 2, "LOW" => 3, "UNKNOWN" => 4}[severity] || 99
|
|
168
175
|
end
|
|
169
176
|
|
|
170
177
|
# Color helpers
|
|
@@ -121,7 +121,7 @@ module Bundler
|
|
|
121
121
|
|
|
122
122
|
# Add severity filtering if configured
|
|
123
123
|
severity_filter = @config.severity_filter
|
|
124
|
-
args += ["--severity", severity_filter.join(",")] if severity_filter
|
|
124
|
+
args += ["--severity", severity_filter.join(",")] if severity_filter&.any?
|
|
125
125
|
|
|
126
126
|
args << @project_root
|
|
127
127
|
args
|
|
@@ -88,7 +88,8 @@ module Bundler
|
|
|
88
88
|
|
|
89
89
|
# Returns an array of all available fixed versions.
|
|
90
90
|
#
|
|
91
|
-
# Parses the fixed_version string and splits on commas
|
|
91
|
+
# Parses the fixed_version string and splits on commas, extracting
|
|
92
|
+
# version numbers from requirement constraints (e.g., "~> 7.1.5" -> "7.1.5").
|
|
92
93
|
#
|
|
93
94
|
# @return [Array<String>] Array of fixed version strings, empty if no fix available
|
|
94
95
|
#
|
|
@@ -97,7 +98,16 @@ module Bundler
|
|
|
97
98
|
def fixed_versions
|
|
98
99
|
return [] unless fixable?
|
|
99
100
|
|
|
100
|
-
fixed_version.split(",").map(&:strip)
|
|
101
|
+
fixed_version.split(",").map(&:strip).filter_map do |constraint|
|
|
102
|
+
# Parse as a requirement (e.g., "~> 7.1.5" or ">= 7.1.5.2")
|
|
103
|
+
Gem::Requirement.new(constraint)
|
|
104
|
+
# Extract the version number from the requirement
|
|
105
|
+
# For "~> 7.1.5" -> "7.1.5", ">= 7.1.5.2" -> "7.1.5.2"
|
|
106
|
+
constraint.match(/\d+(?:\.\d+)*/)&.to_s
|
|
107
|
+
rescue ArgumentError
|
|
108
|
+
# If it's not a valid requirement, try to extract version directly
|
|
109
|
+
constraint.match(/\d+(?:\.\d+)*/)&.to_s
|
|
110
|
+
end.compact.reject(&:empty?)
|
|
101
111
|
end
|
|
102
112
|
|
|
103
113
|
# Returns the most applicable fixed version for the installed version.
|
|
@@ -117,9 +127,21 @@ module Bundler
|
|
|
117
127
|
begin
|
|
118
128
|
installed = Gem::Version.new(installed_version)
|
|
119
129
|
|
|
120
|
-
|
|
130
|
+
# Find versions in same major.minor series
|
|
131
|
+
same_series = fixed_versions.select do |v|
|
|
121
132
|
fixed = Gem::Version.new(v)
|
|
122
133
|
fixed.segments[0..1] == installed.segments[0..1]
|
|
134
|
+
rescue ArgumentError
|
|
135
|
+
false
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Return the minimum version in the same series, or the overall minimum
|
|
139
|
+
target_versions = same_series.empty? ? fixed_versions : same_series
|
|
140
|
+
target_versions.min_by do |v|
|
|
141
|
+
Gem::Version.new(v)
|
|
142
|
+
rescue ArgumentError
|
|
143
|
+
# If version parsing fails, use a very high version to sort it last
|
|
144
|
+
Gem::Version.new("999.999.999")
|
|
123
145
|
end
|
|
124
146
|
rescue ArgumentError
|
|
125
147
|
# If version parsing fails, return the first fixed version
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bundler-trivy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Durable Programming LLC
|
|
@@ -65,6 +65,20 @@ dependencies:
|
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '1.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: standard
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 1.35.1
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 1.35.1
|
|
68
82
|
description: Automatically scans Ruby dependencies for vulnerabilities using Trivy
|
|
69
83
|
after bundle install. Provides configurable security policies, CI/CD integration,
|
|
70
84
|
and comprehensive vulnerability reporting.
|