githack 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45b9752319cd83954a52829df8728540731f5fe7
4
- data.tar.gz: 99461ea4306976cdcedfea9927d13b778c96fda4
3
+ metadata.gz: a900b5b7270b5e428ca145df3ff430d2ba06d936
4
+ data.tar.gz: 7f63c2b10228956cc19120b2787bebcdfbb560bb
5
5
  SHA512:
6
- metadata.gz: e5908cddcecc60d86ba4ccf49a9685af8e930ccdf88d9a48507c2bfb442e7ec0274460c01ae1e2e85f800042d6e43723fcda6dd8090b53c080575dfd789b26af
7
- data.tar.gz: 6da3344fb2cbd29c67d0648d947bfa82b0a9a09b04a47497f4db7825072632500864fd1b9a25258b623d9dbb28a1329e925b8f2f8c4f5140d44249ea43b87848
6
+ metadata.gz: 071452db5375ca0af30f609e9432b90b2b636cd494309be220375d519665476c59a548f3176785a0da81244643a423bcd6d1878e70aae55b50a7f0c485042e86
7
+ data.tar.gz: 6f92e2fdf1374fdd0171921a41ed44add19aa473ad7fdfa682852dd5ffbe277db4b27410a1833c1ac503d471156ed0b98cc05156e279f11a3264c7ed2cf24ac3
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- githack (0.2.0)
4
+ githack (0.3.0)
5
5
  git (~> 1.5)
6
6
  tty-spinner (~> 0.8)
7
7
 
@@ -38,4 +38,4 @@ DEPENDENCIES
38
38
  rspec (~> 3.0)
39
39
 
40
40
  BUNDLED WITH
41
- 1.16.1
41
+ 1.16.3
data/README.md CHANGED
@@ -2,18 +2,16 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/githack.svg)](https://rubygems.org/gems/githack)
4
4
 
5
- Crawl [Git][git]'s commits of a given repository to find forgotten credentials
5
+ Crawl [Git][git]'s commits of a given repository to find forgotten credentials according to given framework.
6
6
 
7
- Currently support:
7
+ > [See documentation ](https://www.rubydoc.info/gems/githack/Githack/Repositories) to know which framework is currently supported
8
8
 
9
- - [Ruby on Rails](https://rubyonrails.org)
10
-
11
- - _config/secrets.yml_
12
- - _config/database.yml_
13
9
 
14
10
  ## Dependencies
15
11
 
16
- You need to install [Git][git]. Exemple for Debian based distributions:
12
+ You need to install [Git][git].
13
+
14
+ Exemple for Debian based distributions:
17
15
 
18
16
  ```bash
19
17
  $ sudo apt install git
@@ -44,31 +42,44 @@ Simply use tis to clone the remote repository in your temporary folder
44
42
  ```ruby
45
43
  require 'githack'
46
44
 
47
- repository = Githack::RailsRepository.new 'https://github.com/RaspberryCook/website'
45
+ repository = Githack::Repositories::Rails::v4.new 'https://github.com/RaspberryCook/website'
48
46
  ```
49
47
 
50
- And then you can search on repository like this:
48
+ And then you can search on repository using `databases` or `secrets` who returns `Array<Githack::Leak>`. `Githack::Leak` contains `sha`, `file` and `content`:
51
49
 
52
50
  ```ruby
53
- repository.search_rails_config_database
54
- # [{"adapter"=>"mysql2", "database"=>"raspberry_cook", "encoding"=>"utf8", "username"=>"raspberry_cook", "password"=>"secret", "host"=>"localhost", "pool"=>5, "timeout"=>5000}])
55
-
56
- repository.search_rails_config_secrets
57
- # [{"development"=>{"marmiton_password"=>"20462046"}, "production"=>{"marmiton_password"=>"20462046"}, "test"=>{"marmiton_password"=>"20462046"}}])
51
+ repository.databases.each do |leak|
52
+ # <Githack::Leak:Githack::Leak:0x00556db18af998 ... >,
53
+ puts leak.sha
54
+ # => 566fac779248c345192512423770f14cf4af1435
55
+ puts leak.file
56
+ # => /tmp/https___github_com_madeindjs_fooder/config/database.yml
57
+ puts leak.content
58
+ # "development:\n" +
59
+ # " adapter: mysql2\n" +
60
+ # " database: raspberry_cook\n" +
61
+ # " encoding: utf8\n" +
62
+ # " username: raspberry_cook\n" +
63
+ # " password: secret\n" +
64
+ # " host: localhost\n" +
65
+ end
66
+
67
+ repository.secrets.each do |leak|
68
+ # ....
69
+ end
58
70
  ```
59
71
 
60
72
  Theses methods will:
61
73
 
62
74
  1. Search all commit were file changed
63
75
  2. Checkout on theses commit to get file content
64
- 3. Filter only usefull informations
65
76
 
66
77
  ### As command line tool
67
78
 
68
79
  Simply use
69
80
 
70
81
  ```bash
71
- $ githack.rb https://github.com/RaspberryCook/website
82
+ $ githack.rb --framework=Rails::V4 https://github.com/madeindjs/fooder
72
83
  ```
73
84
 
74
85
  ## Development
@@ -79,7 +90,35 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
79
90
 
80
91
  ## Contributing
81
92
 
82
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/githack. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/madeindjs/githack. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
94
+
95
+ ### Add new framwork to support
96
+
97
+ Fork this repository & create a new file based on `Githack::Repositories::Rails`
98
+
99
+ ```bash
100
+ $ cp lib/githack/repositories/rails.rb
101
+ ```
102
+
103
+ Then simply overwride
104
+
105
+ ```ruby
106
+ # lib/githack/repositories/your_framework.rb
107
+ module Githack
108
+ module Repositories
109
+ # Module who hold all version of your framework
110
+ module YourFramework
111
+ # Represent a version of your framework
112
+ class V1 < Githack::Repository
113
+ # Represent the path to secrets files
114
+ DATABASE_PATHS = [File.join('config', 'database.php')].freeze
115
+ # Represent the path to database configuration files
116
+ SECRET_PATH = [File.join('config', 'secrets.yml')].freeze
117
+ end
118
+ end
119
+ end
120
+ end
121
+ ```
83
122
 
84
123
  ## Code of Conduct
85
124
 
@@ -8,14 +8,19 @@ url = nil
8
8
 
9
9
  options = {
10
10
  skip_config_secrets: false,
11
- skip_config_database: false
11
+ skip_config_database: false,
12
+ framework: nil
12
13
  }
13
14
 
14
- OptionParser.new do |opts|
15
+ optparse = OptionParser.new do |opts|
15
16
  opts.banner = 'Usage: githack.rb URL with URL as remote URL of a Git repository (currently works only for Rails project)'
16
17
 
17
18
  url = ARGV.pop
18
19
 
20
+ opts.on '-f', '--framework FRAMEWORK', 'Specify repository framework to target to find leaked data', 'use without parameter to get the complete list' do |framework|
21
+ options[:framework] = framework
22
+ end
23
+
19
24
  opts.on '--skip_config_secrets', 'Not search for config/secrets.yml' do |_o|
20
25
  options[:skip_config_secrets] = true
21
26
  end
@@ -24,22 +29,41 @@ OptionParser.new do |opts|
24
29
  options[:skip_config_secrets] = true
25
30
  end
26
31
 
32
+ opts.on('-h', '--help', 'Display this screen') do
33
+ puts opts
34
+ exit
35
+ end
36
+
27
37
  unless url
28
38
  puts "You must provide a Git remote URL\r\n\r\n"
29
39
  puts opts
30
40
  exit
31
41
  end
32
- end.parse!
42
+ end
43
+
44
+ optparse.parse!
45
+
46
+ unless Githack::Repositories.get_availables_frameworks_versions_pretty.include?(options[:framework])
47
+
48
+ puts "You must specify framework\r\n\r\n"
49
+ Githack::Repositories.get_availables_frameworks_versions_pretty.each do |framework|
50
+ puts format(' - %s', framework)
51
+ end
52
+
53
+ exit
54
+ end
55
+
56
+ framework_class = Githack::Repositories.const_get(options[:framework])
33
57
 
34
58
  spinner = TTY::Spinner.new '[:spinner] Cloning repository ...'
35
59
  spinner.auto_spin
36
- repository = Githack::RailsRepository.new url
60
+ repository = framework_class.new url
37
61
  spinner.stop('Done!')
38
62
 
39
63
  unless options[:skip_config_database]
40
64
  spinner = TTY::Spinner.new '[:spinner] Search in config/database.yml (Rails) ...'
41
65
  spinner.auto_spin
42
- result = repository.search_rails_config_database
66
+ result = repository.databases
43
67
  spinner.stop('Done!')
44
68
  pp result
45
69
  end
@@ -47,7 +71,7 @@ end
47
71
  unless options[:skip_config_secrets]
48
72
  spinner = TTY::Spinner.new '[:spinner] Search in config/secrets.yml (Rails) ...'
49
73
  spinner.auto_spin
50
- result = repository.search_rails_config_secrets
74
+ result = repository.secrets
51
75
  spinner.stop('Done!')
52
76
  pp result
53
77
  end
@@ -1,6 +1,42 @@
1
1
  require 'githack/version'
2
- require 'githack/rails_repository'
2
+ require 'githack/repositories/cakephp'
3
+ require 'githack/repositories/laravel'
4
+ require 'githack/repositories/rails'
5
+ require 'githack/repositories/symfony'
6
+ require 'githack/leak'
3
7
 
4
8
  module Githack
5
- # Your code goes here...
9
+ # Represent frameworks available to parse leaked data
10
+ module Repositories
11
+ # Get all class available as repository
12
+ #
13
+ # @return [Array<Class>]
14
+ def self.get_availables_frameworks_versions
15
+ available = []
16
+
17
+ frameworks = Githack::Repositories.constants.select do |c|
18
+ Githack::Repositories.const_get(c).is_a? Module
19
+ end
20
+
21
+ frameworks.each do |framework|
22
+ framework_module = Githack::Repositories.const_get(framework)
23
+
24
+ Githack::Repositories.const_get(framework).constants.each do |v|
25
+ v_class = framework_module.const_get(v)
26
+ available << v_class if v_class.is_a? Class
27
+ end
28
+ end
29
+
30
+ available
31
+ end
32
+
33
+ # Get all class available as repository as pretty string
34
+ #
35
+ # @return [Array<String>]
36
+ def self.get_availables_frameworks_versions_pretty
37
+ Repositories.get_availables_frameworks_versions.map do |framework|
38
+ framework.to_s.gsub('Githack::Repositories::', '')
39
+ end.sort
40
+ end
41
+ end
6
42
  end
@@ -0,0 +1,11 @@
1
+ module Githack
2
+ class Leak
3
+ attr_reader :sha, :content, :file
4
+
5
+ def initialize(sha, file)
6
+ @sha = sha
7
+ @file = file
8
+ @content = File.read(file)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ require 'githack/repository'
2
+
3
+ module Githack
4
+ module Repositories
5
+ module CakePHP
6
+ class V3 < Githack::Repository
7
+ DATABASE_PATHS = [
8
+ File.join('config', 'app.php')
9
+ ].freeze
10
+
11
+ # SECRET_PATH = ['config', 'secrets.yml']
12
+ end
13
+
14
+ class V2 < Githack::Repository
15
+ DATABASE_PATHS = [
16
+ File.join('app', 'Config', 'database.php')
17
+ ].freeze
18
+
19
+ # SECRET_PATH = ['config', 'secrets.yml']
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'githack/repository'
2
+
3
+ module Githack
4
+ module Repositories
5
+ module Laravel
6
+ class V5 < Githack::Repository
7
+ DATABASE_PATHS = [
8
+ File.join('config', 'database.php')
9
+ ].freeze
10
+
11
+ # SECRET_PATH = ['config', 'secrets.yml']
12
+ end
13
+
14
+ class V4 < V5
15
+ DATABASE_PATHS = [
16
+ File.join('app', 'config', 'database.php')
17
+ ].freeze
18
+
19
+ # SECRET_PATH = ['config', 'secrets.yml']
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'githack/repository'
2
+
3
+ module Githack
4
+ module Repositories
5
+ module Rails
6
+ class V5 < Githack::Repository
7
+ SECRET_PATHS = [
8
+ File.join('config', 'secrets.yml')
9
+ ].freeze
10
+
11
+ DATABASE_PATHS = [
12
+ File.join('config', 'database.yml')
13
+ ].freeze
14
+ end
15
+
16
+ class V4 < V5
17
+ end
18
+
19
+ class V3 < V5
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ require 'githack/repository'
2
+
3
+ module Githack
4
+ module Repositories
5
+ module Symfony
6
+ class V4 < Githack::Repository
7
+ SECRET_PATHS = ['.env'].freeze
8
+
9
+ # https://symfony.com/doc/4.1/doctrine.html
10
+ DATABASE_PATHS = [
11
+ File.join('config', 'packages', 'doctrine.yaml'),
12
+ File.join('config', 'packages', 'doctrine.xml'),
13
+ File.join('config', 'packages', 'doctrine.php')
14
+ ].freeze
15
+ end
16
+
17
+ class V3 < Githack::Repository
18
+ SECRET_PATHS = ['.env'].freeze
19
+
20
+ # https://symfony.com/doc/3.3/doctrine.html
21
+ DATABASE_PATHS = [
22
+ File.join('app', 'config', 'parameters.xml'),
23
+ File.join('app', 'config', 'parameters.yml'),
24
+ File.join('app', 'config', 'parameters.php')
25
+ ].freeze
26
+ end
27
+
28
+ class V2 < Githack::Repository
29
+ SECRET_PATHS = ['.env'].freeze
30
+
31
+ # https://symfony.com/doc/2.8/doctrine.html
32
+ DATABASE_PATHS = [
33
+ File.join('app', 'config', 'config.xml'),
34
+ File.join('app', 'config', 'config.yml'),
35
+ File.join('app', 'config', 'config.php')
36
+ ].freeze
37
+ end
38
+
39
+ class V1 < Githack::Repository
40
+ SECRET_PATHS = [].freeze
41
+
42
+ # https://symfony.com/legacy/doc/reference/1_4/en/07-Databases
43
+ DATABASE_PATHS = [
44
+ File.join('config', 'databases.yml')
45
+ ].freeze
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,11 +1,17 @@
1
1
  require 'tmpdir'
2
2
  require 'yaml'
3
3
  require 'git'
4
+ require 'githack/leak'
4
5
 
5
6
  module Githack
6
7
  class Repository
7
8
  attr_reader :git, :remote, :name, :path
8
9
 
10
+ # Represent the path to secrets files
11
+ SECRET_PATH = [].freeze
12
+ # Represent the path to database configuration files
13
+ DATABASE_PATH = [].freeze
14
+
9
15
  def initialize(remote)
10
16
  @remote = remote
11
17
  @name = remote.gsub /[^0-9A-Z]/i, '_'
@@ -18,40 +24,61 @@ module Githack
18
24
  end
19
25
  end
20
26
 
21
- protected
27
+ # Get all changements for config/secrets.yml file (who contains some API keys)
28
+ #
29
+ # @return [Array<Githack::Leak>]
30
+ def secrets
31
+ leaks = []
32
+ files = self.class::SECRET_PATHS.map { |f| File.join(@path, f) }
22
33
 
23
- # Checkout on all file changes
34
+ get_leaks(*files).each do |leak|
35
+ leaks << leak
36
+ yield lead if block_given?
37
+ end
38
+ leaks
39
+ end
40
+
41
+ # Get all changements for config/database.yml file (who contains database configuration for Ruby on Rails Framework)
24
42
  #
25
- # @param file <String> absolute filepath
26
- # @yield <Hash> YAML file parsed
27
- def checkout_on_yaml_file_change(file)
28
- checkout_on_file_change(file) do
29
- begin
30
- data = YAML.safe_load(File.read(file))
31
- yield data
32
- rescue Psych::SyntaxError => e
33
- # can't parse YAML file
34
- end
43
+ # @return [Array<Githack::Leak>]
44
+ def databases
45
+ leaks = []
46
+ files = self.class::DATABASE_PATHS.map { |f| File.join(@path, f) }
47
+
48
+ get_leaks(*files).each do |leak|
49
+ leaks << leak
50
+ yield lead if block_given?
35
51
  end
52
+ leaks
36
53
  end
37
54
 
55
+ protected
56
+
38
57
  # Checkout on all file changes
39
58
  #
40
- # @param file <String> absolute filepath
41
- # @yield <Git::Log>
42
- def checkout_on_file_change(file)
59
+ # @yield [Githack::Leak]
60
+ def get_leaks(*files)
61
+ leaks = []
43
62
  @git.checkout 'master'
44
- begin
45
- @git.log.object(file).each do |commit|
46
- @git.checkout commit
47
- next unless File.exist? file
48
63
 
49
- yield commit
64
+ files.each do |file|
65
+ begin
66
+ @git.log.object(file).each do |commit|
67
+ @git.checkout commit
68
+ next unless File.exist? file
69
+
70
+ leak = Githack::Leak.new(commit.sha, file)
71
+ leaks << leak
72
+
73
+ yield leak if block_given?
74
+ end
75
+ rescue StandardError
76
+ Psych::BadAlias
50
77
  end
51
- rescue StandardError
52
- Psych::BadAlias
78
+ @git.checkout 'master'
53
79
  end
54
- @git.checkout 'master'
80
+
81
+ leaks
55
82
  end
56
83
  end
57
84
  end
@@ -1,3 +1,3 @@
1
1
  module Githack
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: githack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rousseau Alexandre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-19 00:00:00.000000000 Z
11
+ date: 2018-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git
@@ -101,7 +101,11 @@ files:
101
101
  - bin/setup
102
102
  - githack.gemspec
103
103
  - lib/githack.rb
104
- - lib/githack/rails_repository.rb
104
+ - lib/githack/leak.rb
105
+ - lib/githack/repositories/cakephp.rb
106
+ - lib/githack/repositories/laravel.rb
107
+ - lib/githack/repositories/rails.rb
108
+ - lib/githack/repositories/symfony.rb
105
109
  - lib/githack/repository.rb
106
110
  - lib/githack/version.rb
107
111
  homepage: https://github.com/madeindjs/githack
@@ -1,35 +0,0 @@
1
- require 'githack/repository'
2
-
3
- module Githack
4
- class RailsRepository < Repository
5
- # Get all changements for config/secrets.yml file (who contains some API keys)
6
- def search_rails_config_secrets
7
- results = []
8
-
9
- absolute_file_path = File.join @path, 'config', 'secrets.yml'
10
-
11
- checkout_on_yaml_file_change(absolute_file_path) do |secrets|
12
- results << secrets
13
- end
14
-
15
- results.uniq
16
- end
17
-
18
- # Get all changements for config/database.yml file (who contains database configuration for Ruby on Rails Framework)
19
- def search_rails_config_database
20
- results = []
21
-
22
- absolute_file_path = File.join @path, 'config', 'database.yml'
23
-
24
- checkout_on_yaml_file_change(absolute_file_path) do |configs|
25
- configs.each do |config|
26
- config_data = config[1]
27
- next if config_data['adapter'] == 'sqlite3'
28
- results << config_data
29
- end
30
- end
31
-
32
- results.uniq
33
- end
34
- end
35
- end