Class: SastBox::Scanner

Inherits:
Object
  • Object
show all
Includes:
Cwe, OptParser, Printer, Reporter::Sarif, Runner, SeverityCalculator, Snippet
Defined in:
lib/sastbox-sdk/scanner.rb

Constant Summary

Constants included from Cwe

Cwe::ACTIVE_DEBUG_CODE, Cwe::AUTHORIZATION_BYPASS_THROUGH_KEY, Cwe::BASIC_XSS, Cwe::BROKEN_CRYPTO, Cwe::CLEARTEXT_STORAGE_OF_SENSITIVE_INFORMATION, Cwe::CLEARTEXT_TRANSMISSION, Cwe::CODE_INJECTION, Cwe::CSRF, Cwe::DATA_LEAK_BETWEEN_SESSIONS, Cwe::DESERIALIZATION_OF_UNTRUSTED_DATA, Cwe::DIVIDE_BY_ZERO, Cwe::DOWNLOAD_OF_CODE_WITHOUT_INTEGRITY_CHECK, Cwe::ERROR_CONDITION_WITHOUT_ACTION, Cwe::ERROR_CONTAINING_SENSITIVE_INFO, Cwe::EVAL_INJECTION, Cwe::EXPOSED_DANGEROUS_METHOD_OR_FUNCTION, Cwe::EXPOSURE_OF_SYSTEM_DATA, Cwe::EXPOSURE_RESOURCE_WRONG_SPHERE, Cwe::EXPOSURE_SENSITIVE_INFO, Cwe::EXTERNAL_CONTROL_FILE_NAME, Cwe::HARD_CODED_PASSWORD, Cwe::IMPROPER_ACCESS_CONTROL, Cwe::IMPROPER_AUTHENTICATION, Cwe::IMPROPER_AUTHORIZATION, Cwe::IMPROPER_CERT_VALIDATION, Cwe::IMPROPER_CHECK_OF_EXCEPT_COND, Cwe::IMPROPER_CONTROL_DYNAMIC_ATTR, Cwe::IMPROPER_INPUT_VALIDATION, Cwe::IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE, Cwe::IMPROPER_RESTRICTION_MEMORY_BOUNDS, Cwe::IMPROPER_RESTRICTION_OF_RENDERED_UI_LAYERS_OF_FRAMES, Cwe::IMPROPER_RESTRICTION_OF_XML_EXTERNAL_ENTITY_REFERENCE, Cwe::IMPROPER_VERIFICATION_OF_SIGNATURE, Cwe::IMPROPER_WILDCARD_NEUTRALIZATION, Cwe::INADEQUATE_ENCRYPTION_STRENGTH, Cwe::INCLUSION_FUNCTIONALITY_UNTRUSTED_SPHERE, Cwe::INCORRECT_PERMISSION_ASSIGNMENT, Cwe::INCORRECT_REGEX, Cwe::INSECURE_TEMP_FILE, Cwe::INSUFFICIENT_ENTROPY, Cwe::INSUFFICIENT_RANDOM_VALUES, Cwe::INTEGER_OVERFLOW, Cwe::LDAP_INJECTION, Cwe::MULTIPLE_BINDS, Cwe::NULL_POINTER_DEREFERENCE, Cwe::OBSOLETE_FUNCTION, Cwe::OPEN_REDIRECT, Cwe::OS_COMMAND_INJECTION, Cwe::PATH_TRAVERSAL, Cwe::PHP_REMOTE_FILE_INCLUSION, Cwe::PROTECTION_MECHANISM_FAILURE, Cwe::REGEX_WITHOUT_ANCHORS, Cwe::RELIANCE_ON_UNTRUSTED_INPUTS_IN_A_SECURITY_DECISION, Cwe::RESOURCE_CONSUMPTION, Cwe::RESPONSE_SPLITTING, Cwe::SECURITY_MISCONFIGURATION, Cwe::SELECTION_OF_LESS_SECURE_ALGORITHM_DURING_NEGOTIATION, Cwe::SENSITIVE_COOKIE_WITHOUT_HTTPONLY_FLAG, Cwe::SENSITIVE_INFO_IN_SOURCE_CODE_COMMENTS, Cwe::SENSITIVE_INFO_LOG_FILE, Cwe::SESSION_FIXATION, Cwe::SQL_INJECTION, Cwe::SSRF, Cwe::SUSPICIOUS_COMMENT, Cwe::TIMING_DISCREPANCY, Cwe::TOCTOU, Cwe::UNDEF, Cwe::UNINITIALIZED_VARIABLE, Cwe::UNPROTECTED_STORAGE_OF_CREDENTIALS, Cwe::UNRESTRICTED_UPLOAD_OF_FILE_WITH_DANGEROUS_TYPE, Cwe::UNSAFE_REFLECTION, Cwe::UNSALTED_ONE_WAY_HASH, Cwe::USE_OF_EXTERNALLY_CONTROLLED_FORMAT_STRING, Cwe::USE_OF_PERSISTENT_COOKIES, Cwe::USE_OF_POTENTIALLY_DANGEROUS_FUNCTION, Cwe::USE_OF_UNMAINTAINED_THIRD_PARTY_COMPONENTS, Cwe::USE_OF_WEB_LINK_TO_UNTRUSTED_TARGET, Cwe::USING_COMPONENTS_WITH_KNOWN_VULNERABILITIES, Cwe::WEAK_PASSWORD_REQUIREMENT, Cwe::WEAK_PRNG, Cwe::XPATH_INJECTION, Cwe::XQUERY_INJECTION, Cwe::XSS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SeverityCalculator

#add_severity, #attempt_to_determine_severity, #severity_pattern_found?

Methods included from Cwe

#alternative_titles, #cwe_found?, #cwe_start_heuristics, #detected_broken_crypto?, #detected_cmd_injection?, #detected_code_injection?, #detected_csrf?, #detected_deserialization?, #detected_hardcoded_password?, #detected_improper_authentication?, #detected_improper_authorization?, #detected_improper_input_validation?, #detected_null_ptr_deref?, #detected_path_traversal?, #detected_session_fixation?, #detected_sql_injection?, #detected_unrestricted_file_upload?, #detected_xss?, #guess_cwe

Methods included from Reporter::Sarif

#convert_to_sarif_result, #generate_sarif_report, #make_rule, #new_sarif_log, #sarif_runs

Methods included from Snippet

#filename_relative, #snippet_calculate_hashes, #snippet_read, #snippet_read_range

Methods included from Runner

#command?, #run_cmd, #run_cmd_with_timeout

Methods included from Printer

#enable_color, included, #print_debug, #print_error, #print_normal, #print_success, #print_title, #print_warning, #print_with_label

Methods included from OptParser

#parse_opts

Constructor Details

#initialize(params) ⇒ Scanner

Returns a new instance of Scanner.



14
15
16
17
18
19
20
21
22
23
# File 'lib/sastbox-sdk/scanner.rb', line 14

def initialize(params)
  @name = params[:name]
  @name_alias = params[:name_alias] || @name
  @description = params[:description]
  @support = params[:support]
  @version = params[:version]
  @tool = params[:tool]

  @issues = []
end

Instance Attribute Details

#issuesObject

Returns the value of attribute issues.



12
13
14
# File 'lib/sastbox-sdk/scanner.rb', line 12

def issues
  @issues
end

Instance Method Details

#add_hash_issue_v1(issue) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/sastbox-sdk/scanner.rb', line 35

def add_hash_issue_v1(issue) 
  issue[:hash_issue] = ''
  return if got_line_range?(issue)

  scanner_name = @name_alias
  short_filename = issue[:filename].sub(@opts.codebase, '')
  data = [
    scanner_name,
    issue[:title],
    issue[:description],
    short_filename,
    issue[:line].to_s,
    (issue[:snippet][:evidence_line][:hash] || ''),
  ]
  issue[:hash_issue] = Digest::SHA256.hexdigest(data.join(':'))
end

#add_hash_issue_v2(issue) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sastbox-sdk/scanner.rb', line 52

def add_hash_issue_v2(issue)
  filename_path = filename_relative(issue[:filename])
  filename_path = '' if filename_path.nil?
  data = [
    issue[:title],
    issue[:description],
    filename_path,
    got_line_range?(issue) ? "#{issue[:start_line].to_s}-#{issue[:end_line].to_s}" : issue[:line].to_s,
    (issue[:snippet][:evidence_line][:hash]|| ''),
  ]
  issue[:hash_issue_v2] = Digest::SHA256.hexdigest(data.join(':'))
end

#add_issue(issue) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/sastbox-sdk/scanner.rb', line 69

def add_issue(issue)
  return if skip_issue?(issue)
  issue[:tags] = [] unless issue.key? :tags
  add_severity(issue)
  add_hash_issue_v1(issue)
  add_hash_issue_v2(issue)
  guess_cwe(issue)
  @issues << issue
end

#finish_scanObject



110
111
112
113
114
115
# File 'lib/sastbox-sdk/scanner.rb', line 110

def finish_scan
  status = 0
  status = 1 unless @issues.empty?
  print_title("Finished #{@name}")
  status
end

#gen_random_tmp_filename(suffix = '') ⇒ Object



122
123
124
# File 'lib/sastbox-sdk/scanner.rb', line 122

def gen_random_tmp_filename(suffix = '')
  File.join(Dir.tmpdir, "#{SecureRandom.urlsafe_base64}#{suffix}")
end

#gen_random_tmp_filename_jsonObject



126
127
128
# File 'lib/sastbox-sdk/scanner.rb', line 126

def gen_random_tmp_filename_json
  gen_random_tmp_filename('.json')
end

#got_line_range?(issue) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/sastbox-sdk/scanner.rb', line 65

def got_line_range?(issue)
  issue.key?(:start_line) && issue.key?(:end_line)
end

#infoObject



25
26
27
28
29
30
31
32
33
# File 'lib/sastbox-sdk/scanner.rb', line 25

def info
  {
    name: @name,
    description: @description,
    support: @support,
    version: @version,
    sdk_version: SastBox::SDK_VERSION
  }
end

#parse_json_from_file(filename) ⇒ Object



141
142
143
144
145
146
147
# File 'lib/sastbox-sdk/scanner.rb', line 141

def parse_json_from_file(filename)
  content = nil
  if File.exist?(filename)
    content = parse_json_from_str(File.read(filename))
  end
  content
end

#parse_json_from_str(s) ⇒ Object



130
131
132
133
134
135
136
137
138
139
# File 'lib/sastbox-sdk/scanner.rb', line 130

def parse_json_from_str(s)
  content = nil
  unless s.nil?
    begin
      content = JSON.parse(s)
    rescue JSON::ParserError
    end
  end
  content
end

#save_scan_outputObject



117
118
119
120
# File 'lib/sastbox-sdk/scanner.rb', line 117

def save_scan_output
  File.open(@opts.output, "wb") { |file| file.write(generate_sarif_report) }
  print_normal("Sarif result saved to #{@opts.output}", 1)
end

#skip_issue?(issue) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
82
83
# File 'lib/sastbox-sdk/scanner.rb', line 79

def skip_issue?(issue)
  return true if issue[:filename].include?('/.git/')
  return true if issue[:snippet][:read_success] == false
  return false 
end

#start_scanObject



103
104
105
106
107
108
# File 'lib/sastbox-sdk/scanner.rb', line 103

def start_scan
  validate_opts

  print_title("Running #{@name}")
  run
end

#validate_optsObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sastbox-sdk/scanner.rb', line 85

def validate_opts
  enable_color(@opts.color)
  if @opts.info
    puts JSON.pretty_generate(info)
    exit 0
  end

  if @opts.output.nil?
    print_error('output (-o) not passed')
    exit 0
  end

  if @opts.codebase.nil?
    print_error('codebase (-c) not passed')
    exit 0
  end
end