class Dawn::KnowledgeBaseExperimental
This is the YAML powered experimental knowledge base
When the old KB format, using Ruby classes will be marked as deprecated, than this one will be the official.
Dawnscanner KB will be a bunch of YAML file, stored in a hierachy of directories resembling security checks family. A digital signature will be also available to prevent KB tampering.
This class will be accountable for:
+ check for KB upgrade + fetching the KB file from the Internet + verifying the database signature + reading YAML file, creating the security check array
Another big change will be the MVC passed as constructor parameter, so only the checks regarding the particular app, will be loaded in the security check array. This should speed up BasicCheck internal routines.
Class usage will be very simple. After getting the singleton instance, you will load the KB content. The load method will be also responsible about all relevant checks.
Example
require “dawn/knowledge_base_experimental”
…
d = Dawn::KnowledgeBaseExperimental.instance d.update if d.update? d.load
Last update: Fri Oct 7 08:03:43 CEST 2016
Constants
- COMBO_CHECK
- CUSTOM_CHECK
- DEPENDENCY_CHECK
- FILES
- GEM_CHECK
- OS_CHECK
- PATTERN_MATCH_CHECK
- REMOTE_KB_URL_PREFIX
- RUBY_VERSION_CHECK
Attributes
Public Class Methods
# File lib/dawn/knowledge_base_experimental.rb, line 78 def self.kb_descriptor {:kb=>{:version=>"0.0.1", :revision=>Time.now.strftime("%Y%m%d"), :api=>Dawn::VERSION}}.to_yaml end
# File lib/dawn/knowledge_base_experimental.rb, line 65 def initialize(options={}) if $logger.nil? require 'dawn/logger' $logger = Logger.new(STDOUT) $logger.helo "knowledge-base-experimental", Dawn::VERSION end end
Public Instance Methods
# File lib/dawn/knowledge_base_experimental.rb, line 103 def all @security_checks end
# File lib/dawn/knowledge_base_experimental.rb, line 163 def dump(verbose=false) puts "Security checks currently supported:" i=0 KnowledgeBaseExperimental.instance.all.each do |check| i+=1 if verbose puts "Name: #{check.name}\tCVSS: #{check.cvss_score}\tReleased: #{check.release_date}" puts "Description\n#{check.message}" puts "Remediation\n#{check.remediation}\n\n" else puts "#{check.name}" end end puts "-----\nTotal: #{i}" end
# File lib/dawn/knowledge_base_experimental.rb, line 75 def find(name) end
Load security checks from db/ folder.
options - The list of the options to be passed to KB. It can contain:
+ enabled_checks: an array of security checks that must be enabled [:generic_check, :code_quality, :bulletin, :code_style, :owasp_ror_cheatsheet, :owasp_top_10] + mvc: the mvc name for the target application, in order for the KB to deselect all security checks that don't fit the code to be reviewed. + path: the path for the KB root folder. Please note that #{Dir.pwd}/db is the default location.
Returns an array of security checks, matching the mvc to be reviewed and the enabled check list or an empty array if an error occured.
# File lib/dawn/knowledge_base_experimental.rb, line 120 def load(options={}) @security_checks = [] $path = File.join(Dir.pwd, "db") enabled_checks = options[:enabled_checks] unless options[:enabled_checks].nil? mvc = options[:mvc] unless options[:mvc].nil? $path = options[:path] unless options[:path].nil? unless __valid? $logger.error "An invalid library it has been found. Please use --recovery flag to force fresh install from dawnscanner.org" return [] end unless __load? $logger.error "The library must be consumed with dawnscanner up to v#{$descriptor["kb"]["api"]}. You are using dawnscanner v#{Dawn::VERSION}" return [] end # TODO: untar and unzip from here (look for it in Google) if __packed? $logger.info "a packed knowledge base it has been found. Unpacking it" __unpack end enabled_checks.each do |d| dir = File.join($path, d) # Please note that if we enter in this branch, it means someone # tampered the KB between the previous __valid? check and this point. # Of course this is a very rare situation, but we must handle it. unless Dir.exists?(dir) $logger.critical "Missing check directory #{dir}" $logger.error "An invalid library it has been found. Please use --recovery flag to force fresh install from dawnscanner.org" return [] end # Enumerate all YAML file in the give dir end end
# File lib/dawn/knowledge_base_experimental.rb, line 82 def update? FileUtils.mkdir_p("tmp") begin response = Net::HTTP.get URI(REMOTE_KB_URL_PREFIX + "kb.yaml") open("tmp/kb.yaml", "w") do |f| f.puts(response) end response = Net::HTTP.get URI(REMOTE_KB_URL_PREFIX + "kb.yaml.sig") open("tmp/kb.yaml.sig", "w") do |f| f.puts(response) end rescue Exception => e $logger.error e.to_s return false end # Verify kb.yaml signature YAML.load(response) end
Private Instance Methods
# File lib/dawn/knowledge_base_experimental.rb, line 233 def __load? api = $descriptor["kb"]["api"] v = Dawn::VERSION require "dawn/kb/version_check" vc = VersionCheck.new return true if vc.is_higher?(api, v) # => true if v > api return false end
Check if the local KB is packet or not.
Returns true if at least one KB tarball file it has been found in the local DB path
# File lib/dawn/knowledge_base_experimental.rb, line 222 def __packed? FILES.each do |fn| return true if fn.end_with? 'tar.gz' and File.exists?(File.join($path, fn)) end return false end
# File lib/dawn/knowledge_base_experimental.rb, line 229 def __unpack end
# File lib/dawn/knowledge_base_experimental.rb, line 188 def __valid? lines = "" unless File.exists?(File.join($path, "kb.yaml")) $logger.error "Missing kb.yaml in #{path}. Giving up" return false end unless File.exists?(File.join($path, "kb.yaml.sig")) $logger.error "Missing kb.yaml signature in #{path}. Giving up" return false end lines = File.read(File.join($path, "kb.yaml")) hash_file = Digest::SHA256.hexdigest lines hash_orig = File.read(File.join($path, "kb.yaml.sig")) v = __verify_hash(hash_orig, hash_file) if v $logger.info("good kb.yaml file found. Reading knowledge base descriptor") @descriptor = YAML.load(lines) else $logger.error("kb.yaml signature mismatch. Found #{hash_file} while expecting #{hash_orig}. Giving up") return false end return true end
# File lib/dawn/knowledge_base_experimental.rb, line 182 def __verify_hash(original, computed) t=original.split(' ') return false if t.length != 2 return (t[0] == computed) end