Class: Dawn::Core

Inherits:
Object
  • Object
show all
Defined in:
lib/dawn/core.rb

Class Method Summary collapse

Class Method Details

.detect_mvc(target) ⇒ Object

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dawn/core.rb', line 91

def self.detect_mvc(target)

  raise ArgumentError.new("you must set target directory") if target.nil?

  my_dir = Dir.pwd
  Dir.chdir(target)
  raise ArgumentError.new("no Gemfile.lock in #{target}") unless File.exist?("Gemfile.lock")

  lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock"))
  Dir.chdir(my_dir)
  lockfile.specs.each do |s|
    return Dawn::Rails.new(target)    if s.name == "rails"
    return Dawn::Padrino.new(target)  if s.name == "padrino"
  end

  return Dawn::Sinatra.new(target)
end

.dump_knowledge_base(verbose = false) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/dawn/core.rb', line 47

def self.dump_knowledge_base(verbose = false)
  kb = Dawn::KnowledgeBase.new
  lines = []
  lines << "Security checks currently supported:\n"

  kb.all.each do |check|
    if verbose
      lines << "Name: #{check.name}\tCVSS: #{check.cvss_score}\tReleased: #{check.release_date}"
      lines << "Description\n#{check.message}"
      lines << "Remediation\n#{check.remediation}\n\n"
    else
      lines << "#{check.name}"
    end
  end
  lines << "-----\nTotal: #{kb.all.count}"

  lines.empty? ? 0 : lines.compact.join("\n")

end

.find_conf(create_if_none = false) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/dawn/core.rb', line 113

def self.find_conf(create_if_none = false)
  conf_name  = 'codesake-dawn.yaml'
  path_order = [
    './',
    '~/',
    '/usr/local/etc/',
  ]
  path_order.each do |p|
    fn = p + conf_name if p.start_with?('/')
    # if outside $HOME the config file must be hidden
    fn = File.expand_path(p) + '/.'+conf_name if ! p.start_with?('/')
    return fn if File.exist?(fn)
  end

  # Dawn didn't find a config file.
  # If create_if_none flag is set to false, than I'll return nil so the
  # read_conf method will return the default configuration
  return nil unless create_if_none

  # If create_if_none flag is set to true, than I'll create a config file
  # on the current directory with the default configuration.
  conf = {"config"=>{:verbose=>false, :output=>"console", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}}

  # Calculate the conf file path
  conf_path = File.expand_path('~') +'/.'+conf_name

  # Open the conf file and write our default config to it
  File.open(conf_path, 'w') do |f|
    rv = f.write(YAML.dump(conf))
  end

  conf_path
end

.guess_mvc(gemfile_lock) ⇒ Object

guess_mvc is very close to detect_mvc despite it accepts a filename as input and it tries to guess the mvc framework used from the gems it founds in Gemfile.lock without creating an engine.

Raises:

  • (ArgumentError)


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/dawn/core.rb', line 71

def self.guess_mvc(gemfile_lock)
  ret = {:name=>"", :version=>"", :connected_gems=>[]}

  a = []
  my_dir = Dir.pwd
  Dir.chdir(File.dirname(gemfile_lock))
  raise ArgumentError.new("can't read #{gemfile_lock}") unless File.readable?(File.basename(gemfile_lock))

  lockfile = Bundler::LockfileParser.new(Bundler.read_file(File.basename(gemfile_lock)))
  Dir.chdir(my_dir)
  lockfile.specs.each do |s|
    ret = {:name=>s.name, :version=>s.version.to_s} if s.name == "rails" || s.name == "sinatra"
    a << {:name=>s.name, :version=>s.version.to_s}
  end

  ret[:connected_gems]=a
  ret

end

.helpObject

TODO.20140326 All those methods must moved from here to Util class and a Dawn::Core namespace must be created.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/dawn/core.rb', line 9

def self.help
  puts "Usage: dawn [options] target_directory"
  printf "\nExamples:\n"
  puts "\t$ dawn a_sinatra_webapp_directory"
  puts "\t$ dawn -C the_rails_blog_engine"
  puts "\t$ dawn -C --json a_sinatra_webapp_directory"
  puts "\t$ dawn --ascii-tabular-report my_rails_blog_ecommerce"
  puts "\t$ dawn --html -F my_report.html my_rails_blog_ecommerce"
  printf "\n   -r, --rails\t\t\t\t\tforce dawn to consider the target a rails application"
  printf "\n   -s, --sinatra\t\t\t\tforce dawn to consider the target a sinatra application"
  printf "\n   -p, --padrino\t\t\t\tforce dawn to consider the target a padrino application"
  printf "\n   -G, --gem-lock\t\t\t\tforce dawn to scan only for vulnerabilities affecting dependencies in Gemfile.lock"
  printf "\n   -a, --ascii-tabular-report\t\t\tcause dawn to format findings using table in ascii art"
  printf "\n   -j, --json\t\t\t\t\tcause dawn to format findings using json"
  printf "\n   -C, --count-only\t\t\t\tdawn will only count vulnerabilities (useful for scripts)"
  printf "\n   -z, --exit-on-warn\t\t\t\tdawn will return number of found vulnerabilities as exit code"
  printf "\n   -F, --file filename\t\t\t\ttells dawn to write output to filename"
  printf "\n   -c, --config-file filename\t\t\ttells dawn to load configuration from filename"
  printf "\n\nDisable security check family\n"
  printf "\n       --disable-cve-bulletins\t\t\tdisable all CVE security checks"
  printf "\n       --disable-code-quality\t\t\tdisable all code quality checks"
  printf "\n       --disable-code-style\t\t\tdisable all code style checks"
  printf "\n       --disable-owasp-ror-cheatsheet\t\tdisable all Owasp Ruby on Rails cheatsheet checks"
  printf "\n       --disable-owasp-top-10\t\t\tdisable all Owasp Top 10 checks"
  printf "\n\nFlags useful to query Dawn\n"
  printf "\n   -S, --search-knowledge-base [check_name]\tsearch check_name in the knowledge base"
  printf "\n       --list-knowledge-base\t\t\tlist knowledge-base content"
  printf "\n       --list-known-families\t\t\tlist security check families contained in dawn's knowledge base"
  printf "\n       --list-known-framework\t\t\tlist ruby MVC frameworks supported by dawn"
  printf "\n\nService flags\n"
  printf "\n   -D, --debug\t\t\t\t\tenters dawn debug mode"
  printf "\n   -V, --verbose\t\t\t\tthe output will be more verbose"
  printf "\n   -v, --version\t\t\t\tshow version information"
  printf "\n   -h, --help\t\t\t\t\tshow this help\n"

  true
end

.is_good_target?(target) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/dawn/core.rb', line 109

def self.is_good_target?(target)
  (File.exist?(target) and File.directory?(target))
end

.read_conf(file = nil) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/dawn/core.rb', line 147

def self.read_conf(file=nil)
  conf = {:verbose=>false, :output=>"console", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}
  begin
    return conf if file.nil?
    file = file.chop if (not file.nil? and file.end_with? '/')
    return conf if ! File.exist?(file)
  rescue => e
    $logger.err "it seems you've found a bug in core.rb@#{__LINE__}: #{e.message}"
    return conf
  end

  c = YAML.load_file(file)

  cf = c["config"]
  cc = cf[:enabled_checks]

  # TODO
  # I must add some sanity check here
  conf[:verbose] = cf["verbose"] unless cf["verbose"].nil?
  conf[:debug] = cf["debug"] unless cf["debug"].nil?
  conf[:output] = cf["output"] unless cf["output"].nil?
  conf[:enabled_checks] = cc unless cc.nil?

  return conf
end