sastbox_sdk 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9b33ef5c1d3c97a2991c9dcb76b13a3c414df8f545ff3f085b3ebed0f9d7f496
4
+ data.tar.gz: d4c5e354f401f469062f5310cd449980b8e1394bf26931696d0a0e2cf053c9f4
5
+ SHA512:
6
+ metadata.gz: 8784202c7700c39863d9bd94a7d59cac86a16d6a6ebcdba1574f148ed909520743c48c431abb8d9f3fac0eda27dc67a42aeffa3d93653940e1a04939289b3a59
7
+ data.tar.gz: 94c3e307ce99bd94c381db15f6c278dd816f638c4a9cdbf37962777289535b38d7b0abef9a803feb1af2a59ce18b9dc5b6b734493b9057bb46ea184c5359fc0d
data/README.md ADDED
File without changes
@@ -0,0 +1,26 @@
1
+ require 'base64'
2
+ require 'digest'
3
+ require 'json'
4
+ require 'open3'
5
+ require 'optparse'
6
+ require 'ostruct'
7
+ require 'timeout'
8
+ require 'tmpdir'
9
+ require 'securerandom'
10
+
11
+ require_relative 'sastbox-sdk/cwe_constants'
12
+ require_relative 'sastbox-sdk/cwe_detector'
13
+ require_relative 'sastbox-sdk/snippet'
14
+ require_relative 'sastbox-sdk/reporter_sarif'
15
+ require_relative 'sastbox-sdk/opt_parser'
16
+ require_relative 'sastbox-sdk/printer'
17
+ require_relative 'sastbox-sdk/runner'
18
+ require_relative 'sastbox-sdk/severity_calculator'
19
+ require_relative 'sastbox-sdk/scanner'
20
+
21
+
22
+ module SastBox
23
+ VERSION = '2.0.0'
24
+ SDK_VERSION = '0.0.1'
25
+ end
26
+
@@ -0,0 +1,9 @@
1
+ module SastBox
2
+ module Codebase
3
+
4
+ end
5
+ end
6
+
7
+
8
+
9
+
@@ -0,0 +1,87 @@
1
+ module SastBox
2
+ module Cwe
3
+ UNDEF = 0
4
+ IMPROPER_INPUT_VALIDATION = 20
5
+ PATH_TRAVERSAL = 22
6
+ EXTERNAL_CONTROL_FILE_NAME = 73
7
+ OS_COMMAND_INJECTION = 78
8
+ XSS = 79
9
+ BASIC_XSS = 80
10
+ SQL_INJECTION = 89
11
+ LDAP_INJECTION = 90
12
+ CODE_INJECTION = 94
13
+ EVAL_INJECTION = 95
14
+ PHP_REMOTE_FILE_INCLUSION = 98
15
+ RESPONSE_SPLITTING = 113
16
+ IMPROPER_RESTRICTION_MEMORY_BOUNDS = 119
17
+ USE_OF_EXTERNALLY_CONTROLLED_FORMAT_STRING = 134
18
+ IMPROPER_WILDCARD_NEUTRALIZATION = 155
19
+ INCORRECT_REGEX = 185
20
+ INTEGER_OVERFLOW = 190
21
+ EXPOSURE_SENSITIVE_INFO = 200
22
+ TIMING_DISCREPANCY = 208
23
+ ERROR_CONTAINING_SENSITIVE_INFO = 209
24
+ UNPROTECTED_STORAGE_OF_CREDENTIALS = 256
25
+ HARD_CODED_PASSWORD = 259
26
+ IMPROPER_ACCESS_CONTROL = 284
27
+ IMPROPER_AUTHORIZATION = 285
28
+ IMPROPER_AUTHENTICATION = 287
29
+ IMPROPER_CERT_VALIDATION = 295
30
+ CLEARTEXT_STORAGE_OF_SENSITIVE_INFORMATION = 312
31
+ CLEARTEXT_TRANSMISSION = 319
32
+ INADEQUATE_ENCRYPTION_STRENGTH = 326
33
+ BROKEN_CRYPTO = 327
34
+ INSUFFICIENT_RANDOM_VALUES = 330
35
+ INSUFFICIENT_ENTROPY = 331
36
+ WEAK_PRNG = 338
37
+ IMPROPER_VERIFICATION_OF_SIGNATURE = 347
38
+ CSRF = 352
39
+ TOCTOU = 367
40
+ DIVIDE_BY_ZERO = 369
41
+ INSECURE_TEMP_FILE = 377
42
+ SESSION_FIXATION = 384
43
+ ERROR_CONDITION_WITHOUT_ACTION = 390
44
+ RESOURCE_CONSUMPTION = 400
45
+ IMPROPER_RESOURCE_SHUTDOWN_OR_RELEASE = 404
46
+ UNRESTRICTED_UPLOAD_OF_FILE_WITH_DANGEROUS_TYPE = 434
47
+ UNINITIALIZED_VARIABLE = 457
48
+ UNSAFE_REFLECTION = 470
49
+ NULL_POINTER_DEREFERENCE = 476
50
+ OBSOLETE_FUNCTION = 477
51
+ DATA_LEAK_BETWEEN_SESSIONS = 488
52
+ ACTIVE_DEBUG_CODE = 489
53
+ DOWNLOAD_OF_CODE_WITHOUT_INTEGRITY_CHECK = 494
54
+ EXPOSURE_OF_SYSTEM_DATA = 497
55
+ DESERIALIZATION_OF_UNTRUSTED_DATA = 502
56
+ WEAK_PASSWORD_REQUIREMENT = 521
57
+ SENSITIVE_INFO_LOG_FILE = 532
58
+ USE_OF_PERSISTENT_COOKIES = 539
59
+ SUSPICIOUS_COMMENT = 546
60
+ OPEN_REDIRECT = 601
61
+ MULTIPLE_BINDS = 605
62
+ IMPROPER_RESTRICTION_OF_XML_EXTERNAL_ENTITY_REFERENCE = 611
63
+ SENSITIVE_INFO_IN_SOURCE_CODE_COMMENTS = 615
64
+ AUTHORIZATION_BYPASS_THROUGH_KEY = 639
65
+ XPATH_INJECTION = 643
66
+ XQUERY_INJECTION = 652
67
+ EXPOSURE_RESOURCE_WRONG_SPHERE = 668
68
+ USE_OF_POTENTIALLY_DANGEROUS_FUNCTION = 676
69
+ PROTECTION_MECHANISM_FAILURE = 693
70
+ IMPROPER_CHECK_OF_EXCEPT_COND = 703
71
+ INCORRECT_PERMISSION_ASSIGNMENT = 732
72
+ EXPOSED_DANGEROUS_METHOD_OR_FUNCTION = 749
73
+ SELECTION_OF_LESS_SECURE_ALGORITHM_DURING_NEGOTIATION = 757
74
+ UNSALTED_ONE_WAY_HASH = 759
75
+ REGEX_WITHOUT_ANCHORS = 777
76
+ RELIANCE_ON_UNTRUSTED_INPUTS_IN_A_SECURITY_DECISION = 807
77
+ INCLUSION_FUNCTIONALITY_UNTRUSTED_SPHERE = 829
78
+ IMPROPER_CONTROL_DYNAMIC_ATTR = 915
79
+ SSRF = 918
80
+ USING_COMPONENTS_WITH_KNOWN_VULNERABILITIES = 937
81
+ SENSITIVE_COOKIE_WITHOUT_HTTPONLY_FLAG = 1004
82
+ IMPROPER_RESTRICTION_OF_RENDERED_UI_LAYERS_OF_FRAMES = 1021
83
+ USE_OF_WEB_LINK_TO_UNTRUSTED_TARGET = 1022
84
+ SECURITY_MISCONFIGURATION = 1032
85
+ USE_OF_UNMAINTAINED_THIRD_PARTY_COMPONENTS = 1104
86
+ end
87
+ end
@@ -0,0 +1,202 @@
1
+ require 'set'
2
+
3
+ module SastBox
4
+ module Cwe
5
+
6
+ def cwe_found?(issue, patterns, cwe)
7
+ patterns.each do |pattern|
8
+ @alternative_titles.each do |title|
9
+ if title.include? pattern
10
+ issue[:cwe_id] = cwe
11
+ return true
12
+ end
13
+ end
14
+ end
15
+ return false
16
+ end
17
+
18
+ def detected_sql_injection?(issue)
19
+ patterns = [
20
+ 'sql injection',
21
+ 'sqlinj',
22
+ 'sqli',
23
+ 'sql inj'
24
+ ]
25
+ cwe_found?(issue, patterns, SastBox::Cwe::SQL_INJECTION)
26
+ end
27
+
28
+ def detected_xss?(issue)
29
+ patterns = [
30
+ 'xss',
31
+ 'cross-site scripting',
32
+ 'cross site scripting',
33
+ 'html injection'
34
+ ]
35
+ cwe_found?(issue, patterns, SastBox::Cwe::XSS)
36
+ end
37
+
38
+ def detected_cmd_injection?(issue)
39
+ patterns = [
40
+ 'command injection',
41
+ 'command execution',
42
+ 'cmd injection',
43
+ 'cmd execution',
44
+ 'cmd exec',
45
+ 'shell injection',
46
+ 'shell metacharacters'
47
+ ]
48
+ cwe_found?(issue, patterns, SastBox::Cwe::OS_COMMAND_INJECTION)
49
+ end
50
+
51
+ def detected_code_injection?(issue)
52
+ patterns = [
53
+ 'code injection',
54
+ 'code execution',
55
+ 'code exec',
56
+ 'code inj'
57
+ ]
58
+ cwe_found?(issue, patterns, SastBox::Cwe::CODE_INJECTION)
59
+ end
60
+
61
+ def detected_session_fixation?(issue)
62
+ patterns = [
63
+ 'session fixation',
64
+ ]
65
+ cwe_found?(issue, patterns, SastBox::Cwe::SESSION_FIXATION)
66
+ end
67
+
68
+ def detected_csrf?(issue)
69
+ patterns = [
70
+ 'csrf',
71
+ 'xsrf',
72
+ 'cross site request forgery',
73
+ 'session riding',
74
+ 'cross site reference forgery',
75
+ ]
76
+ cwe_found?(issue, patterns, SastBox::Cwe::CSRF)
77
+ end
78
+
79
+ def detected_deserialization?(issue)
80
+ patterns = [
81
+ 'deserializ',
82
+ 'unmarshaling',
83
+ 'unpickling',
84
+ 'php object injection'
85
+ ]
86
+ cwe_found?(issue, patterns, SastBox::Cwe::DESERIALIZATION_OF_UNTRUSTED_DATA)
87
+ end
88
+
89
+ def detected_path_traversal?(issue)
90
+ patterns = [
91
+ 'path traversal',
92
+ 'traversal',
93
+ 'pathtraversal'
94
+ ]
95
+ cwe_found?(issue, patterns, SastBox::Cwe::PATH_TRAVERSAL)
96
+ end
97
+
98
+ def detected_hardcoded_password?(issue)
99
+ patterns = [
100
+ 'hard-coded'
101
+ ]
102
+ cwe_found?(issue, patterns, SastBox::Cwe::HARD_CODED_PASSWORD)
103
+ end
104
+
105
+ def detected_null_ptr_deref?(issue)
106
+ patterns = [
107
+ 'null pointer deref'
108
+ ]
109
+ cwe_found?(issue, patterns, SastBox::Cwe::NULL_POINTER_DEREFERENCE)
110
+ end
111
+
112
+ def detected_broken_crypto?(issue)
113
+ patterns = [
114
+ 'weak cipher',
115
+ 'weak crypto',
116
+ 'insecure cipher',
117
+ 'insecure crypto',
118
+ 'insecure encryption',
119
+ 'broken cipher',
120
+ 'broken crypto',
121
+ 'weak hash',
122
+ 'insecure hash',
123
+ 'broken hash',
124
+ ]
125
+ cwe_found?(issue, patterns, SastBox::Cwe::BROKEN_CRYPTO)
126
+ end
127
+
128
+ def detected_improper_authorization?(issue)
129
+ patterns = [
130
+ 'improper authorization',
131
+ 'no authorization',
132
+ 'broken authorization',
133
+ ]
134
+ cwe_found?(issue, patterns, SastBox::Cwe::IMPROPER_AUTHORIZATION)
135
+ end
136
+
137
+ def detected_improper_authentication?(issue)
138
+ patterns = [
139
+ 'improper authentication',
140
+ 'no authentication',
141
+ 'broken authentication',
142
+ ]
143
+ cwe_found?(issue, patterns, SastBox::Cwe::IMPROPER_AUTHENTICATION)
144
+ end
145
+
146
+ def detected_improper_input_validation?(issue)
147
+ patterns = [
148
+ 'input validation',
149
+ 'data validation',
150
+ ]
151
+ cwe_found?(issue, patterns, SastBox::Cwe::IMPROPER_INPUT_VALIDATION)
152
+ end
153
+
154
+ def detected_unrestricted_file_upload?(issue)
155
+ patterns = [
156
+ 'unrestricted upload',
157
+ 'unrestricted file upload',
158
+ ]
159
+ cwe_found?(issue, patterns, SastBox::Cwe::UNRESTRICTED_UPLOAD_OF_FILE_WITH_DANGEROUS_TYPE)
160
+ end
161
+
162
+ def cwe_start_heuristics(issue)
163
+ alternative_titles(issue)
164
+ issue[:cwe_id] = SastBox::Cwe::UNDEF
165
+ return if detected_sql_injection?(issue)
166
+ return if detected_xss?(issue)
167
+ return if detected_cmd_injection?(issue)
168
+ return if detected_code_injection?(issue)
169
+ return if detected_session_fixation?(issue)
170
+ return if detected_csrf?(issue)
171
+ return if detected_deserialization?(issue)
172
+ return if detected_path_traversal?(issue)
173
+ return if detected_hardcoded_password?(issue)
174
+ return if detected_null_ptr_deref?(issue)
175
+ return if detected_broken_crypto?(issue)
176
+ return if detected_improper_authorization?(issue)
177
+ return if detected_improper_authentication?(issue)
178
+ return if detected_improper_input_validation?(issue)
179
+ return if detected_unrestricted_file_upload?(issue)
180
+ end
181
+
182
+ def alternative_titles(issue)
183
+ @alternative_titles = Set.new
184
+ @alternative_titles << issue[:title].downcase
185
+
186
+ @alternative_titles << @alternative_titles.first.split('_').join(' ')
187
+ @alternative_titles << @alternative_titles.first.split('-').join(' ')
188
+ @alternative_titles << @alternative_titles.first.gsub("hard coded", "hard-coded")
189
+ @alternative_titles << @alternative_titles.first.gsub("hardcoded", "hard-coded")
190
+ @alternative_titles
191
+ end
192
+
193
+ def guess_cwe(issue)
194
+ if issue.key?(:cwe_id)
195
+ cwe_start_heuristics(issue) if [SastBox::Cwe::UNDEF, -1, nil].include?(issue[:cwe_id])
196
+ else
197
+ cwe_start_heuristics(issue)
198
+ end
199
+ end
200
+
201
+ end
202
+ end
@@ -0,0 +1,45 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+
4
+ module SastBox
5
+ module OptParser
6
+ def parse_opts(args)
7
+ @opts = OpenStruct.new
8
+ @opts.verbose = false
9
+ @opts.info = false
10
+ @opts.color = true
11
+ @opts.diff_hashes = []
12
+ @opts.diff_quick = false
13
+ @opts.timeout = 200 * 60
14
+
15
+ opt_parser = OptionParser.new do |opts|
16
+ opts.on('-c', '--codebase=CODEBASE', 'Codebase to be scanned') do |codebase|
17
+ @opts.codebase = codebase
18
+ end
19
+
20
+ opts.on('-o', '--output=OUTPUT', 'Output path to save SARIF result') do |output|
21
+ @opts.output = output
22
+ end
23
+
24
+ opts.on("-v", '--[no-]verbose', 'Run verbosely') do |v|
25
+ @opts.verbose = v
26
+ end
27
+
28
+ opts.on('-t', '--timeout=TIMEOUT', Integer, "Control timeout (default: #{@opts.timeout/60} mins per scanner)") do |timeout|
29
+ @opts.timeout = timeout * 60
30
+ end
31
+
32
+ opts.on("-i", '--info', 'Info about the scanner') do
33
+ @opts.info = true
34
+ end
35
+
36
+ opts.on('-n', '--[no-]color', 'Enable/disable coloring') do |v|
37
+ @opts.color = v
38
+ end
39
+ end
40
+
41
+ opt_parser.parse!(args)
42
+ @opts
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,86 @@
1
+ require 'colored'
2
+ require 'date'
3
+
4
+ module SastBox
5
+ module Printer
6
+
7
+ def enable_color(flag = true)
8
+ @color = flag
9
+ end
10
+
11
+ def print_title(s, level = 0)
12
+ pad = " " * (level * 4)
13
+ out_s = "#{pad}[*] #{s}"
14
+ if @color
15
+ puts out_s.bold.blue
16
+ else
17
+ puts out_s
18
+ end
19
+ @logger.info(out_s) if instance_variable_defined?("@logger")
20
+ end
21
+
22
+ def print_normal(s, level = 0)
23
+ pad = " " * (level * 4)
24
+ out_s = "#{pad}#{s}"
25
+ puts out_s
26
+ @logger.info(out_s) if instance_variable_defined?("@logger")
27
+ end
28
+
29
+ def print_success(s, level = 0)
30
+ pad = " " * (level * 4)
31
+ out_s = "#{pad}[SUCCESS] #{s}"
32
+ if @color
33
+ puts out_s.bold.green
34
+ else
35
+ puts out_s
36
+ end
37
+ @logger.info(out_s) if instance_variable_defined?("@logger")
38
+ end
39
+
40
+ def print_error(s, level = 0)
41
+ pad = " " * (level * 4)
42
+ out_s = "#{pad}[ ERROR ] #{s}"
43
+ if @color
44
+ puts out_s.bold.red
45
+ else
46
+ puts out_s
47
+ end
48
+ @logger.error(out_s) if instance_variable_defined?("@logger")
49
+ end
50
+
51
+ def print_with_label(s, label, level = 0)
52
+ pad = " " * (level * 4)
53
+ out_s = "#{pad}[#{label}] #{s}"
54
+ puts out_s
55
+ @logger.info(out_s) if instance_variable_defined?("@logger")
56
+ end
57
+
58
+ def print_debug(s, level = 0)
59
+ pad = " " * (level * 4)
60
+ now = DateTime.now.strftime('%d/%m/%Y %H:%M:%S.%3N')
61
+ out_s = "#{pad}DEBUG|#{now}| #{s}"
62
+ if @color
63
+ puts out_s.bold.yellow
64
+ else
65
+ puts out_s
66
+ end
67
+ @logger.debug(out_s) if instance_variable_defined?("@logger")
68
+ end
69
+
70
+ def print_warning(s, level = 0)
71
+ pad = " " * (level * 4)
72
+ out_s = "#{pad}[WARNING] #{s}"
73
+ if @color
74
+ puts out_s.bold.yellow
75
+ else
76
+ puts out_s
77
+ end
78
+ @logger.info(out_s) if instance_variable_defined?("@logger")
79
+ end
80
+
81
+ def self.included(base)
82
+ #base.instance_variable_set(:@color, true)
83
+ end
84
+
85
+ end
86
+ end