legendary 0.1.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/legendary +5 -0
- data/legendary.gemspec +29 -0
- data/lib/legendary/gems.rb +29 -0
- data/lib/legendary/info.rb +56 -0
- data/lib/legendary/repository.rb +28 -0
- data/lib/legendary/rspec.rb +13 -0
- data/lib/legendary/runner.rb +24 -0
- data/lib/legendary/version.rb +3 -0
- data/lib/legendary/vulnerabilities.rb +45 -0
- data/lib/legendary.rb +27 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d3c324fc5c9231e59d724fa09bdc2aa0acf3ab4c
|
4
|
+
data.tar.gz: fad40b6afeb4395295b740acb733a7c8d61dcd48
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 89451a2ad1542006b6b57b8314d6828a46981d11dcb67b143fecd369143d90e16eb7fcc79ee4b1fc073cd34af05a34de09395dbce00cedece8cd0ce8ea87a796
|
7
|
+
data.tar.gz: 23cd3daa76f1415153d4d5b1c3d4850b7dc604749748768132777915468ada41da640d8744d0e6779f05683be2d8e631abc9eeaa9c0a1e665b6570a9624c4369
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Legendary
|
2
|
+
|
3
|
+
Ruby Gem Vulnerability Checker.
|
4
|
+
|
5
|
+
Started as a fork of [gemsurance](github.com/appfolio/gemsurance).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'legendary'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install legendary
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
$ bundle exec legendary
|
26
|
+
|
27
|
+
RSpec integration (in your spec/spec_helper.rb)
|
28
|
+
|
29
|
+
require 'legendary/rspec'
|
30
|
+
|
31
|
+
in a spec file
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
describe Project::Application do
|
35
|
+
specify { is_expected.to be_secure }
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
## Development
|
40
|
+
|
41
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
42
|
+
|
43
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
1. Fork it ( https://github.com/jobready/legendary/fork )
|
48
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
49
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
50
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
51
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "legendary"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/exe/legendary
ADDED
data/legendary.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'legendary/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "legendary"
|
8
|
+
spec.version = Legendary::VERSION
|
9
|
+
spec.authors = ["John D'Agostino"]
|
10
|
+
spec.email = ["johnd@jobready.com.au"]
|
11
|
+
|
12
|
+
spec.summary = %q{A Legendary Gem to Detect Security Vulnerabilities}
|
13
|
+
spec.description = %q{A simple gem that helps detect security vulnerabilities and outdated gems}
|
14
|
+
spec.homepage = "https://github.com/jobready/legendary"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
23
|
+
|
24
|
+
spec.add_dependency "bundler", "~> 1.9"
|
25
|
+
spec.add_dependency "activesupport", "~> 4.2.1"
|
26
|
+
spec.add_dependency "git", "~> 1.2"
|
27
|
+
spec.add_dependency "gems", "~> 0.8"
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Legendary
|
2
|
+
class Gems
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :bundler
|
6
|
+
|
7
|
+
delegate :dependencies, to: :bundler
|
8
|
+
delegate :specs, to: :bundler
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@bundler = Bundler.load
|
12
|
+
end
|
13
|
+
|
14
|
+
def each
|
15
|
+
specs.each do |spec|
|
16
|
+
yield Legendary::Info.new(spec,
|
17
|
+
dependencies,
|
18
|
+
definitions)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def definitions
|
23
|
+
# TODO: locking from gemsurance
|
24
|
+
@definitions ||= Bundler.definition(true).tap do |definition|
|
25
|
+
definition.resolve_remotely!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Legendary
|
2
|
+
class Info
|
3
|
+
attr_accessor :name, :spec, :version, :gemfile, :dependencies, :definitions
|
4
|
+
|
5
|
+
delegate :homepage_uri, to: :meta
|
6
|
+
delegate :name, to: :spec
|
7
|
+
delegate :version, to: :spec
|
8
|
+
delegate :git_version, to: :spec
|
9
|
+
delegate :version, to: :latest, prefix: true
|
10
|
+
|
11
|
+
def initialize(spec, dependencies, definitions)
|
12
|
+
@spec = spec
|
13
|
+
@dependencies = dependencies
|
14
|
+
@definitions = definitions
|
15
|
+
end
|
16
|
+
|
17
|
+
def git_outdated?
|
18
|
+
git_version != latest.git_version
|
19
|
+
end
|
20
|
+
|
21
|
+
def gemfile
|
22
|
+
dependencies.any? do |other|
|
23
|
+
other.name == name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def outdated?
|
28
|
+
Gem::Version.new(latest_version) > Gem::Version.new(version)
|
29
|
+
end
|
30
|
+
|
31
|
+
def vulnerable?
|
32
|
+
# FIXME: speeds things up, but in theory a
|
33
|
+
# a gem might not have a release, but have vulnerable
|
34
|
+
return false unless (outdated? || git_outdated?)
|
35
|
+
return vulnerabilities.any?
|
36
|
+
end
|
37
|
+
|
38
|
+
def vulnerabilities
|
39
|
+
@vulnerabilities ||= Vulnerabilities.new(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def meta
|
43
|
+
@meta ||= ::Gems.info(name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def latest
|
47
|
+
@latest ||= definitions.index[name].sort_by { |b| b.version }.last
|
48
|
+
end
|
49
|
+
|
50
|
+
def prerelease
|
51
|
+
if !version.prerelease? && latest.size > 1
|
52
|
+
latest.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Legendary
|
2
|
+
class Repository
|
3
|
+
DB_REPO = 'https://github.com/rubysec/ruby-advisory-db'
|
4
|
+
|
5
|
+
attr_accessor :path
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
end
|
10
|
+
|
11
|
+
def repo_exists?
|
12
|
+
File.directory?(File.join(path, '/.git/'))
|
13
|
+
end
|
14
|
+
|
15
|
+
def clone
|
16
|
+
Git.clone(DB_REPO, path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def pull
|
20
|
+
repo = Git.open(path)
|
21
|
+
repo.pull
|
22
|
+
end
|
23
|
+
|
24
|
+
def clone_or_update
|
25
|
+
repo_exists? ? pull : clone
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Legendary
|
2
|
+
class Runner
|
3
|
+
def initialize(path='/tmp/.legendary-repo')
|
4
|
+
Legendary.repository = Repository.new(path)
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
Legendary.logger.info("Updating Repository")
|
9
|
+
Legendary.repository.clone_or_update
|
10
|
+
|
11
|
+
Legendary.logger.info("Loading Gems")
|
12
|
+
|
13
|
+
Gems.new.each do |gem|
|
14
|
+
if gem.outdated?
|
15
|
+
puts "#{gem.name} is outdated. #{gem.version} -> #{gem.latest_version} (it is a #{gem.gemfile ? 'in your gemfile' : 'dependency'})"
|
16
|
+
end
|
17
|
+
|
18
|
+
if gem.vulnerable?
|
19
|
+
puts "#{gem.name} is vulnerable."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Legendary
|
2
|
+
class Vulnerabilities
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(info)
|
6
|
+
@info = info
|
7
|
+
end
|
8
|
+
|
9
|
+
def path
|
10
|
+
@path ||= File.join(Legendary.repository.path,
|
11
|
+
@info.name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def exists?
|
15
|
+
File.exists?(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def each
|
19
|
+
return nil unless exists?
|
20
|
+
|
21
|
+
Legendary.logger.info("#{@info.name} : #{path}")
|
22
|
+
|
23
|
+
Dir.foreach(path) do |yaml_file|
|
24
|
+
info = YAML.load(yaml_file)
|
25
|
+
|
26
|
+
Legendary.logger.info("#{@info.name}: #{info}")
|
27
|
+
|
28
|
+
affected = (vulnerability.patched_versions || []).none?(satisfied_version)
|
29
|
+
patched = (vulnerability.unaffected_versions || []).none?(satisfied_version)
|
30
|
+
|
31
|
+
if affected || patched
|
32
|
+
yield info
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def satisfied_version(version)
|
40
|
+
Gem::Requirement.new(version.split(',')).satisfied_by?(@info.version)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
data/lib/legendary.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'git'
|
3
|
+
require 'erb'
|
4
|
+
require 'gems'
|
5
|
+
require 'logger'
|
6
|
+
require 'active_support/core_ext/module/delegation'
|
7
|
+
|
8
|
+
module Legendary
|
9
|
+
def self.repository
|
10
|
+
@repository ||= Repository.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.repository=(repository)
|
14
|
+
@repository = repository
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.logger
|
18
|
+
@logger ||= ::Logger.new(STDOUT)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'legendary/version'
|
23
|
+
require 'legendary/vulnerabilities'
|
24
|
+
require 'legendary/repository'
|
25
|
+
require 'legendary/gems'
|
26
|
+
require 'legendary/info'
|
27
|
+
require 'legendary/runner'
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: legendary
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John D'Agostino
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 4.2.1
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 4.2.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: git
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: gems
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.8'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.8'
|
97
|
+
description: A simple gem that helps detect security vulnerabilities and outdated
|
98
|
+
gems
|
99
|
+
email:
|
100
|
+
- johnd@jobready.com.au
|
101
|
+
executables:
|
102
|
+
- legendary
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- ".gitignore"
|
107
|
+
- ".rspec"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- bin/console
|
113
|
+
- bin/setup
|
114
|
+
- exe/legendary
|
115
|
+
- legendary.gemspec
|
116
|
+
- lib/legendary.rb
|
117
|
+
- lib/legendary/gems.rb
|
118
|
+
- lib/legendary/info.rb
|
119
|
+
- lib/legendary/repository.rb
|
120
|
+
- lib/legendary/rspec.rb
|
121
|
+
- lib/legendary/runner.rb
|
122
|
+
- lib/legendary/version.rb
|
123
|
+
- lib/legendary/vulnerabilities.rb
|
124
|
+
homepage: https://github.com/jobready/legendary
|
125
|
+
licenses: []
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.2.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: A Legendary Gem to Detect Security Vulnerabilities
|
147
|
+
test_files: []
|
148
|
+
has_rdoc:
|