rubion 0.3.16 → 0.3.17
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/lib/rubion/scanner.rb +73 -8
- data/lib/rubion/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d382653589bad6b28b68444b231efafa582f375cf1d4c7284d8df5faae04d50
|
|
4
|
+
data.tar.gz: 3edfba9269ed3024943544887422101b7512cd4309c5e689fbd6f8a7cf655a60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5f3c72e3d1f257c426e0df25efb3b1ae62751527324bd5a8991986dd12aa6652cb0ca81aecd2941c3b00a19a5ceff090d1718ff5d540e59c0ddbc509707dd73
|
|
7
|
+
data.tar.gz: bc17b9ebd3c5081cb040deba4358eae42f4a941169fa7a5db919ea9ef92065dfa33fcb11dcc0a2925e58a62ebbb9ea4dad3364c69ff46133b7a2f79447885503
|
data/lib/rubion/scanner.rb
CHANGED
|
@@ -125,14 +125,17 @@ module Rubion
|
|
|
125
125
|
def check_gem_versions
|
|
126
126
|
stdout, stderr, status = Open3.capture3('bundle outdated --parseable', chdir: @project_path)
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
# bundle outdated returns exit code 1 when outdated gems are found (expected behavior)
|
|
129
|
+
# Exit code 0 means no outdated gems or command succeeded
|
|
130
|
+
# Exit code 1 means outdated gems found - this is success, not an error
|
|
131
|
+
if status.success? || status.exitstatus == 1
|
|
132
|
+
# Command succeeded or outdated gems found - parse output
|
|
130
133
|
parse_bundle_outdated_output(stdout)
|
|
131
134
|
elsif status.exitstatus.nil?
|
|
132
135
|
# Command not found or failed to execute
|
|
133
136
|
raise "bundle outdated command failed or is not available. Error: #{stderr}"
|
|
134
137
|
else
|
|
135
|
-
# Command failed with non-zero exit code
|
|
138
|
+
# Command failed with unexpected non-zero exit code
|
|
136
139
|
raise "bundle outdated failed with exit code #{status.exitstatus}. Output: #{stdout}#{unless stderr.empty?
|
|
137
140
|
"\nError: #{stderr}"
|
|
138
141
|
end}"
|
|
@@ -148,16 +151,22 @@ module Rubion
|
|
|
148
151
|
if status.exitstatus.nil?
|
|
149
152
|
# Command not found or failed to execute
|
|
150
153
|
raise "#{@package_manager} audit command failed or is not available. Error: #{stderr}"
|
|
151
|
-
elsif !status.success? && status.exitstatus != 1
|
|
152
|
-
# Exit code 1 is expected when vulnerabilities are found
|
|
154
|
+
elsif !status.success? && status.exitstatus != 1 && status.exitstatus != 4
|
|
155
|
+
# Exit code 1 (npm) or 4 (yarn) is expected when vulnerabilities are found
|
|
156
|
+
# Other non-zero codes are errors
|
|
153
157
|
raise "#{@package_manager} audit failed with exit code #{status.exitstatus}. Output: #{stdout}#{unless stderr.empty?
|
|
154
158
|
"\nError: #{stderr}"
|
|
155
159
|
end}"
|
|
156
160
|
end
|
|
157
161
|
|
|
158
162
|
begin
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
# Yarn audit outputs JSON line by line, need to parse each line
|
|
164
|
+
if @package_manager == 'yarn'
|
|
165
|
+
parse_yarn_audit_output(stdout)
|
|
166
|
+
else
|
|
167
|
+
data = JSON.parse(stdout)
|
|
168
|
+
parse_npm_audit_output(data)
|
|
169
|
+
end
|
|
161
170
|
rescue JSON::ParserError => e
|
|
162
171
|
raise "Failed to parse #{@package_manager} audit JSON output: #{e.message}. Raw output: #{stdout}"
|
|
163
172
|
end
|
|
@@ -364,6 +373,55 @@ module Rubion
|
|
|
364
373
|
@result.package_vulnerabilities = vulnerabilities
|
|
365
374
|
end
|
|
366
375
|
|
|
376
|
+
def parse_yarn_audit_output(output)
|
|
377
|
+
vulnerabilities = []
|
|
378
|
+
seen_advisories = {}
|
|
379
|
+
|
|
380
|
+
# Yarn audit outputs JSON line by line
|
|
381
|
+
output.each_line do |line|
|
|
382
|
+
next if line.strip.empty?
|
|
383
|
+
|
|
384
|
+
begin
|
|
385
|
+
json_obj = JSON.parse(line)
|
|
386
|
+
next unless json_obj.is_a?(Hash)
|
|
387
|
+
|
|
388
|
+
# Parse auditAdvisory type
|
|
389
|
+
if json_obj['type'] == 'auditAdvisory' && json_obj['data'] && json_obj['data']['advisory']
|
|
390
|
+
advisory = json_obj['data']['advisory']
|
|
391
|
+
advisory_id = advisory['id']
|
|
392
|
+
|
|
393
|
+
# Skip if we've already seen this advisory
|
|
394
|
+
next if seen_advisories[advisory_id]
|
|
395
|
+
|
|
396
|
+
seen_advisories[advisory_id] = true
|
|
397
|
+
|
|
398
|
+
# Extract package name and version from findings
|
|
399
|
+
if advisory['findings'] && advisory['findings'].is_a?(Array) && advisory['findings'].first
|
|
400
|
+
finding = advisory['findings'].first
|
|
401
|
+
version = finding['version'] || 'unknown'
|
|
402
|
+
else
|
|
403
|
+
version = 'unknown'
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Get severity (yarn uses lowercase)
|
|
407
|
+
severity = (advisory['severity'] || 'unknown').downcase
|
|
408
|
+
|
|
409
|
+
vulnerabilities << {
|
|
410
|
+
package: advisory['module_name'] || 'unknown',
|
|
411
|
+
version: version,
|
|
412
|
+
severity: severity,
|
|
413
|
+
title: advisory['title'] || advisory['overview'] || 'Vulnerability detected'
|
|
414
|
+
}
|
|
415
|
+
end
|
|
416
|
+
rescue JSON::ParserError
|
|
417
|
+
# Skip invalid JSON lines
|
|
418
|
+
next
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
@result.package_vulnerabilities = vulnerabilities
|
|
423
|
+
end
|
|
424
|
+
|
|
367
425
|
def parse_npm_outdated_output(data)
|
|
368
426
|
versions = []
|
|
369
427
|
|
|
@@ -789,7 +847,14 @@ module Rubion
|
|
|
789
847
|
puts "\n Both npm and yarn are available. Which would you like to use?"
|
|
790
848
|
print " Enter 'n' for npm or 'y' for yarn (default: npm): "
|
|
791
849
|
|
|
792
|
-
|
|
850
|
+
input = $stdin.gets
|
|
851
|
+
if input.nil?
|
|
852
|
+
# stdin not available (e.g., running through bundle exec in non-interactive mode)
|
|
853
|
+
puts " (stdin not available, using npm as default)\n"
|
|
854
|
+
return 'npm'
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
choice = input.chomp.strip.downcase
|
|
793
858
|
|
|
794
859
|
if choice.empty? || choice == 'n' || choice == 'npm'
|
|
795
860
|
'npm'
|
data/lib/rubion/version.rb
CHANGED