pwn 0.5.442 → 0.5.444

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +3 -3
  4. data/bin/pwn_sast +1 -0
  5. data/lib/pwn/plugins/file_fu.rb +20 -22
  6. data/lib/pwn/sast/amqp_connect_as_guest.rb +12 -91
  7. data/lib/pwn/sast/apache_file_system_util_api.rb +11 -93
  8. data/lib/pwn/sast/aws.rb +13 -95
  9. data/lib/pwn/sast/banned_function_calls_c.rb +140 -219
  10. data/lib/pwn/sast/base64.rb +12 -92
  11. data/lib/pwn/sast/beef_hook.rb +10 -92
  12. data/lib/pwn/sast/cmd_execution_go_lang.rb +83 -0
  13. data/lib/pwn/sast/cmd_execution_java.rb +14 -93
  14. data/lib/pwn/sast/cmd_execution_python.rb +16 -95
  15. data/lib/pwn/sast/cmd_execution_ruby.rb +24 -103
  16. data/lib/pwn/sast/cmd_execution_scala.rb +14 -93
  17. data/lib/pwn/sast/csrf.rb +10 -92
  18. data/lib/pwn/sast/deserial_java.rb +19 -98
  19. data/lib/pwn/sast/emoticon.rb +17 -100
  20. data/lib/pwn/sast/eval.rb +10 -92
  21. data/lib/pwn/sast/factory.rb +15 -95
  22. data/lib/pwn/sast/http_authorization_header.rb +20 -102
  23. data/lib/pwn/sast/inner_html.rb +10 -92
  24. data/lib/pwn/sast/keystore.rb +10 -92
  25. data/lib/pwn/sast/local_storage.rb +11 -93
  26. data/lib/pwn/sast/location_hash.rb +10 -92
  27. data/lib/pwn/sast/log4j.rb +12 -91
  28. data/lib/pwn/sast/logger.rb +24 -106
  29. data/lib/pwn/sast/md5.rb +10 -92
  30. data/lib/pwn/sast/outer_html.rb +10 -92
  31. data/lib/pwn/sast/padding_oracle.rb +11 -93
  32. data/lib/pwn/sast/password.rb +15 -97
  33. data/lib/pwn/sast/php_input_mechanisms.rb +18 -97
  34. data/lib/pwn/sast/php_type_juggling.rb +16 -95
  35. data/lib/pwn/sast/pom_version.rb +1 -3
  36. data/lib/pwn/sast/port.rb +16 -98
  37. data/lib/pwn/sast/post_message.rb +10 -92
  38. data/lib/pwn/sast/private_key.rb +10 -92
  39. data/lib/pwn/sast/redirect.rb +13 -95
  40. data/lib/pwn/sast/redos.rb +16 -98
  41. data/lib/pwn/sast/shell.rb +18 -100
  42. data/lib/pwn/sast/signature.rb +10 -92
  43. data/lib/pwn/sast/sql.rb +19 -95
  44. data/lib/pwn/sast/ssl.rb +14 -96
  45. data/lib/pwn/sast/sudo.rb +10 -92
  46. data/lib/pwn/sast/task_tag.rb +23 -105
  47. data/lib/pwn/sast/test_case_engine.rb +188 -0
  48. data/lib/pwn/sast/throw_errors.rb +14 -96
  49. data/lib/pwn/sast/token.rb +12 -94
  50. data/lib/pwn/sast/type_script_type_juggling.rb +16 -95
  51. data/lib/pwn/sast/version.rb +12 -94
  52. data/lib/pwn/sast/window_location_hash.rb +10 -92
  53. data/lib/pwn/sast.rb +5 -0
  54. data/lib/pwn/version.rb +1 -1
  55. data/lib/pwn.rb +0 -2
  56. data/spec/lib/pwn/sast/cmd_execution_go_lang_spec.rb +25 -0
  57. data/spec/lib/pwn/sast/test_case_engine_spec.rb +20 -0
  58. data/third_party/pwn_rdoc.jsonl +1 -1
  59. metadata +7 -3
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'json'
4
+ require 'socket'
5
+
6
+ module PWN
7
+ module SAST
8
+ # SAST Module used to execute PWN::SAST::* modules
9
+ module TestCaseEngine
10
+ @@logger = PWN::Plugins::PWNLogger.create
11
+
12
+ # Supported Method Parameters::
13
+ # PWN::SAST::TestCaseEngine.execute(
14
+ # test_case_filter: 'required - grep command to filter results',
15
+ # security_references: 'required - Hash with keys :sast_module, :section, :nist_800_53_uri, :cwe_id, :cwe_uri',
16
+ # dir_path: 'optional - path to dir defaults to .',
17
+ # include_extensions: 'optional - array of file extensions to search for in scan (Defaults to all file types / i.e. [])',
18
+ # exclude_extensions: 'optional - array of file extensions to exclude from scan (Defaults to [.bin, .dat, .JS-BEAUTIFIED, .o, .test, .png, .jpg, .jpeg, .gif, .svg, .ico, .so, .spec, .zip, .tar, .gz, .tgz, .7z, .mp3, .mp4, .mov, .avi, .wmv, .flv, .mkv])',
19
+ # git_repo_root_uri: 'optional - http uri of git repo scanned'
20
+ # )
21
+
22
+ public_class_method def self.execute(opts = {})
23
+ test_case_filter = opts[:test_case_filter]
24
+ raise 'ERROR: test_case_filter must be nil' if test_case_filter.nil?
25
+
26
+ security_references = opts[:security_references]
27
+ raise 'ERROR: security_references must be a Hash' unless security_references.is_a?(Hash)
28
+
29
+ dir_path = opts[:dir_path] ||= '.'
30
+ include_extensions = opts[:include_extensions] ||= []
31
+ exclude_extensions = opts[:exclude_extentions] ||= %w[
32
+ .7z
33
+ .avi
34
+ .bin
35
+ .dat
36
+ .dll
37
+ .flv
38
+ .gif
39
+ .gz
40
+ .ico
41
+ .jpg
42
+ .jpeg
43
+ .JS-BEAUTIFIED
44
+ .markdown
45
+ .md
46
+ .mkv
47
+ .mov
48
+ .mp3
49
+ .mp4
50
+ .o
51
+ .png
52
+ .svg
53
+ .test
54
+ .so
55
+ .spec
56
+ .tar
57
+ .tgz
58
+ .webm
59
+ .wmv
60
+ .zip
61
+ ]
62
+
63
+ git_repo_root_uri = opts[:git_repo_root_uri].to_s.scrub
64
+
65
+ result_arr = []
66
+ ai_introspection = PWN::Env[:ai][:introspection]
67
+ logger_results = "AI Introspection => #{ai_introspection} => "
68
+
69
+ PWN::Plugins::FileFu.recurse_in_dir(
70
+ dir_path: dir_path,
71
+ include_extensions: include_extensions,
72
+ exclude_extensions: exclude_extensions
73
+ ) do |entry|
74
+ if File.file?(entry) && File.basename(entry) !~ /^pwn.+(html|json|db)$/ && entry !~ /test/i
75
+ line_no_and_contents_arr = []
76
+ entry_beautified = false
77
+
78
+ if File.extname(entry) == '.js' && (`wc -l #{entry}`.split.first.to_i < 20 || entry.include?('.min.js') || entry.include?('-all.js'))
79
+ js_beautify = `js-beautify #{entry} > #{entry}.JS-BEAUTIFIED 2> /dev/null`.to_s.scrub
80
+ entry = "#{entry}.JS-BEAUTIFIED"
81
+ entry_beautified = true
82
+ end
83
+
84
+ # Replace tokenized test_case_filter, PWN_ENTRY with actual entry
85
+ this_test_case_filter = test_case_filter.to_s.gsub('{PWN_SAST_SRC_TARGET}', entry.to_s.scrub).to_s.scrub
86
+ str = `#{this_test_case_filter}`.to_s.scrub
87
+
88
+ if str.to_s.empty?
89
+ # If str length is >= 64 KB do not include results. (Due to Mongo Document Size Restrictions)
90
+ logger_results = "#{logger_results}~" # Catching bugs is good :)
91
+ else
92
+ str = "1:Result larger than 64KB -> Size: #{str.to_s.length}. Please click the \"Path\" link for more details." if str.to_s.length >= 64_000
93
+
94
+ hash_line = {
95
+ timestamp: Time.now.strftime('%Y-%m-%d %H:%M:%S.%9N %z').to_s,
96
+ security_references: security_references,
97
+ filename: { git_repo_root_uri: git_repo_root_uri, entry: entry },
98
+ line_no_and_contents: '',
99
+ raw_content: str,
100
+ test_case_filter: this_test_case_filter
101
+ }
102
+
103
+ # COMMMENT: Must be a better way to implement this (regex is kinda funky)
104
+ line_contents_split = str.split(/^(\d{1,}):|\n(\d{1,}):/)[1..-1]
105
+ line_no_count = line_contents_split.length # This should always be an even number
106
+ current_count = 0
107
+ while line_no_count > current_count
108
+ line_no = line_contents_split[current_count]
109
+ contents = line_contents_split[current_count + 1]
110
+ if Dir.exist?('.git')
111
+ repo_root = '.'
112
+
113
+ author = PWN::Plugins::Git.get_author(
114
+ repo_root: repo_root,
115
+ from_line: line_no,
116
+ to_line: line_no,
117
+ target_file: entry,
118
+ entry_beautified: entry_beautified
119
+ )
120
+ end
121
+ author ||= 'N/A'
122
+
123
+ ai_analysis = nil
124
+ if ai_introspection
125
+ request = {
126
+ scm_uri: "#{hash_line[:filename][:git_repo_root_uri]}/#{hash_line[:filename][:entry]}",
127
+ line_no: line_no,
128
+ source_code_snippet: contents
129
+ }.to_json
130
+ response = PWN::AI::Introspection.reflect(request: request)
131
+ if response.is_a?(Hash)
132
+ ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
133
+ ai_analysis = response[:choices].last[:content] if response[:choices].last.keys.include?(:content)
134
+ end
135
+ end
136
+
137
+ hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
138
+ line_no: line_no,
139
+ contents: contents,
140
+ author: author,
141
+ ai_analysis: ai_analysis
142
+ )
143
+
144
+ current_count += 2
145
+ end
146
+ result_arr.push(hash_line)
147
+ logger_results = "#{logger_results}x" # Seeing progress is good :)
148
+ end
149
+ end
150
+ end
151
+ logger_banner = "http://#{Socket.gethostname}:8808/doc_root/pwn-#{PWN::VERSION.to_s.scrub}/#{to_s.scrub.gsub('::', '/')}.html"
152
+ if logger_results.empty?
153
+ @@logger.info("#{logger_banner}: No files applicable to this test case.\n")
154
+ else
155
+ @@logger.info("#{logger_banner} => #{logger_results}complete.\n")
156
+ end
157
+ result_arr
158
+ rescue StandardError => e
159
+ raise e
160
+ end
161
+
162
+ # Author(s):: 0day Inc. <support@0dayinc.com>
163
+
164
+ public_class_method def self.authors
165
+ "AUTHOR(S):
166
+ 0day Inc. <support@0dayinc.com>
167
+ "
168
+ end
169
+
170
+ # Display Usage for this Module
171
+
172
+ public_class_method def self.help
173
+ puts "USAGE:
174
+ sast_arr = #{self}.execute(
175
+ test_case_filter: 'required grep command to filter results',
176
+ security_references: 'required Hash with keys :sast_module, :section, :nist_800_53_uri, :cwe_id, :cwe_uri',
177
+ dir_path: 'optional path to dir defaults to .',
178
+ include_extensions: 'optional array of file extensions to search for in scan (Defaults to all file types / i.e. [])',
179
+ exclude_extensions: 'optional array of file extensions to exclude from scan (Defaults to [.bin, .dat, .JS-BEAUTIFIED, .o, .test, .png, .jpg, .jpeg, .gif, .svg, .ico, .so, .spec, .zip, .tar, .gz, .tgz, .7z, .mp3, .mp4, .mov, .avi, .wmv, .flv, .mkv])',
180
+ git_repo_root_uri: 'optional http uri of git repo scanned'
181
+ )
182
+
183
+ #{self}.authors
184
+ "
185
+ end
186
+ end
187
+ end
188
+ end
@@ -8,8 +8,6 @@ module PWN
8
8
  # SAST Module used to identify whether
9
9
  # error messages are sanitized properly.
10
10
  module ThrowErrors
11
- @@logger = PWN::Plugins::PWNLogger.create
12
-
13
11
  # Supported Method Parameters::
14
12
  # PWN::SAST::ThrowErrors.scan(
15
13
  # dir_path: 'optional path to dir defaults to .'
@@ -19,101 +17,21 @@ module PWN
19
17
  public_class_method def self.scan(opts = {})
20
18
  dir_path = opts[:dir_path]
21
19
  git_repo_root_uri = opts[:git_repo_root_uri].to_s.scrub
22
- result_arr = []
23
- ai_introspection = PWN::Env[:ai][:introspection]
24
- logger_results = "AI Introspection => #{ai_introspection} => "
25
-
26
- PWN::Plugins::FileFu.recurse_in_dir(dir_path: dir_path) do |entry|
27
- if (File.file?(entry) && File.basename(entry) !~ /^pwn.+(html|json|db)$/ && File.basename(entry) !~ /\.JS-BEAUTIFIED$/) && entry !~ /test/i
28
- line_no_and_contents_arr = []
29
- entry_beautified = false
30
-
31
- if File.extname(entry) == '.js' && (`wc -l #{entry}`.split.first.to_i < 20 || entry.include?('.min.js') || entry.include?('-all.js'))
32
- js_beautify = `js-beautify #{entry} > #{entry}.JS-BEAUTIFIED 2> /dev/null`.to_s.scrub
33
- entry = "#{entry}.JS-BEAUTIFIED"
34
- entry_beautified = true
35
- end
36
-
37
- test_case_filter = %(
38
- grep -in \
39
- -e panic \
40
- -e raise \
41
- -e throw #{entry} 2> /dev/null | \
42
- grep '"'
43
- )
44
-
45
- str = `#{test_case_filter}`.to_s.scrub
46
-
47
- if str.to_s.empty?
48
- # If str length is >= 64 KB do not include results. (Due to Mongo Document Size Restrictions)
49
- logger_results = "#{logger_results}~" # Catching bugs is good :)
50
- else
51
- str = "1:Result larger than 64KB -> Size: #{str.to_s.length}. Please click the \"Path\" link for more details." if str.to_s.length >= 64_000
52
-
53
- hash_line = {
54
- timestamp: Time.now.strftime('%Y-%m-%d %H:%M:%S.%9N %z').to_s,
55
- security_references: security_references,
56
- filename: { git_repo_root_uri: git_repo_root_uri, entry: entry },
57
- line_no_and_contents: '',
58
- raw_content: str,
59
- test_case_filter: test_case_filter
60
- }
61
-
62
- # COMMMENT: Must be a better way to implement this (regex is kinda funky)
63
- line_contents_split = str.split(/^(\d{1,}):|\n(\d{1,}):/)[1..-1]
64
- line_no_count = line_contents_split.length # This should always be an even number
65
- current_count = 0
66
- while line_no_count > current_count
67
- line_no = line_contents_split[current_count]
68
- contents = line_contents_split[current_count + 1]
69
- if Dir.exist?('.git')
70
- repo_root = '.'
71
-
72
- author = PWN::Plugins::Git.get_author(
73
- repo_root: repo_root,
74
- from_line: line_no,
75
- to_line: line_no,
76
- target_file: entry,
77
- entry_beautified: entry_beautified
78
- )
79
- end
80
- author ||= 'N/A'
81
-
82
- ai_analysis = nil
83
- if ai_introspection
84
- request = {
85
- scm_uri: "#{hash_line[:filename][:git_repo_root_uri]}/#{hash_line[:filename][:entry]}",
86
- line_no: line_no,
87
- source_code_snippet: contents
88
- }.to_json
89
- response = PWN::AI::Introspection.reflect(request: request)
90
- if response.is_a?(Hash)
91
- ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
92
- ai_analysis = response[:choices].last[:content] if response[:choices].last.keys.include?(:content)
93
- end
94
- end
95
-
96
- hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
97
- line_no: line_no,
98
- contents: contents,
99
- author: author,
100
- ai_analysis: ai_analysis
101
- )
102
20
 
103
- current_count += 2
104
- end
105
- result_arr.push(hash_line)
106
- logger_results = "#{logger_results}x" # Seeing progress is good :)
107
- end
108
- end
109
- end
110
- logger_banner = "http://#{Socket.gethostname}:8808/doc_root/pwn-#{PWN::VERSION.to_s.scrub}/#{to_s.scrub.gsub('::', '/')}.html"
111
- if logger_results.empty?
112
- @@logger.info("#{logger_banner}: No files applicable to this test case.\n")
113
- else
114
- @@logger.info("#{logger_banner} => #{logger_results}complete.\n")
115
- end
116
- result_arr
21
+ test_case_filter = %(
22
+ grep -in \
23
+ -e panic \
24
+ -e raise \
25
+ -e throw {PWN_SAST_SRC_TARGET} 2> /dev/null | \
26
+ grep '"'
27
+ )
28
+
29
+ PWN::SAST::TestCaseEngine.execute(
30
+ test_case_filter: test_case_filter,
31
+ security_references: security_references,
32
+ dir_path: dir_path,
33
+ git_repo_root_uri: git_repo_root_uri
34
+ )
117
35
  rescue StandardError => e
118
36
  raise e
119
37
  end
@@ -8,8 +8,6 @@ module PWN
8
8
  # SAST Module used to identify any
9
9
  # reference within source code of authorization tokens.
10
10
  module Token
11
- @@logger = PWN::Plugins::PWNLogger.create
12
-
13
11
  # Supported Method Parameters::
14
12
  # PWN::SAST::Token.scan(
15
13
  # dir_path: 'optional path to dir defaults to .'
@@ -19,100 +17,20 @@ module PWN
19
17
  public_class_method def self.scan(opts = {})
20
18
  dir_path = opts[:dir_path]
21
19
  git_repo_root_uri = opts[:git_repo_root_uri].to_s.scrub
22
- result_arr = []
23
- ai_introspection = PWN::Env[:ai][:introspection]
24
- logger_results = "AI Introspection => #{ai_introspection} => "
25
-
26
- PWN::Plugins::FileFu.recurse_in_dir(dir_path: dir_path) do |entry|
27
- if File.file?(entry) && File.basename(entry) !~ /^pwn.+(html|json|db)$/ && File.basename(entry) !~ /\.JS-BEAUTIFIED$/ && entry !~ /test/i
28
- line_no_and_contents_arr = []
29
- entry_beautified = false
30
-
31
- if File.extname(entry) == '.js' && (`wc -l #{entry}`.split.first.to_i < 20 || entry.include?('.min.js') || entry.include?('-all.js'))
32
- js_beautify = `js-beautify #{entry} > #{entry}.JS-BEAUTIFIED 2> /dev/null`.to_s.scrub
33
- entry = "#{entry}.JS-BEAUTIFIED"
34
- entry_beautified = true
35
- end
36
-
37
- test_case_filter = "
38
- grep -Fin \
39
- -e 'token' \
40
- -e 'oauth' \
41
- -e 'decodeAndVerify' #{entry} 2> /dev/null
42
- "
43
-
44
- str = `#{test_case_filter}`.to_s.scrub
45
-
46
- if str.to_s.empty?
47
- # If str length is >= 64 KB do not include results. (Due to Mongo Document Size Restrictions)
48
- logger_results = "#{logger_results}~" # Catching bugs is good :)
49
- else
50
- str = "1:Result larger than 64KB -> Size: #{str.to_s.length}. Please click the \"Path\" link for more details." if str.to_s.length >= 64_000
51
20
 
52
- hash_line = {
53
- timestamp: Time.now.strftime('%Y-%m-%d %H:%M:%S.%9N %z').to_s,
54
- security_references: security_references,
55
- filename: { git_repo_root_uri: git_repo_root_uri, entry: entry },
56
- line_no_and_contents: '',
57
- raw_content: str,
58
- test_case_filter: test_case_filter
59
- }
60
-
61
- # COMMMENT: Must be a better way to implement this (regex is kinda funky)
62
- line_contents_split = str.split(/^(\d{1,}):|\n(\d{1,}):/)[1..-1]
63
- line_no_count = line_contents_split.length # This should always be an even number
64
- current_count = 0
65
- while line_no_count > current_count
66
- line_no = line_contents_split[current_count]
67
- contents = line_contents_split[current_count + 1]
68
- if Dir.exist?('.git')
69
- repo_root = '.'
70
-
71
- author = PWN::Plugins::Git.get_author(
72
- repo_root: repo_root,
73
- from_line: line_no,
74
- to_line: line_no,
75
- target_file: entry,
76
- entry_beautified: entry_beautified
77
- )
78
- end
79
- author ||= 'N/A'
80
-
81
- ai_analysis = nil
82
- if ai_introspection
83
- request = {
84
- scm_uri: "#{hash_line[:filename][:git_repo_root_uri]}/#{hash_line[:filename][:entry]}",
85
- line_no: line_no,
86
- source_code_snippet: contents
87
- }.to_json
88
- response = PWN::AI::Introspection.reflect(request: request)
89
- if response.is_a?(Hash)
90
- ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
91
- ai_analysis = response[:choices].last[:content] if response[:choices].last.keys.include?(:content)
92
- end
93
- end
94
-
95
- hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
96
- line_no: line_no,
97
- contents: contents,
98
- author: author,
99
- ai_analysis: ai_analysis
100
- )
21
+ test_case_filter = "
22
+ grep -Fin \
23
+ -e 'token' \
24
+ -e 'oauth' \
25
+ -e 'decodeAndVerify' {PWN_SAST_SRC_TARGET} 2> /dev/null
26
+ "
101
27
 
102
- current_count += 2
103
- end
104
- result_arr.push(hash_line)
105
- logger_results = "#{logger_results}x" # Seeing progress is good :)
106
- end
107
- end
108
- end
109
- logger_banner = "http://#{Socket.gethostname}:8808/doc_root/pwn-#{PWN::VERSION.to_s.scrub}/#{to_s.scrub.gsub('::', '/')}.html"
110
- if logger_results.empty?
111
- @@logger.info("#{logger_banner}: No files applicable to this test case.\n")
112
- else
113
- @@logger.info("#{logger_banner} => #{logger_results}complete.\n")
114
- end
115
- result_arr
28
+ PWN::SAST::TestCaseEngine.execute(
29
+ test_case_filter: test_case_filter,
30
+ security_references: security_references,
31
+ dir_path: dir_path,
32
+ git_repo_root_uri: git_repo_root_uri
33
+ )
116
34
  rescue StandardError => e
117
35
  raise e
118
36
  end
@@ -8,8 +8,6 @@ module PWN
8
8
  # SAST Module used to identify loose comparisons
9
9
  # (i.e. == instead of ===) within TypeScript source code.
10
10
  module TypeScriptTypeJuggling
11
- @@logger = PWN::Plugins::PWNLogger.create
12
-
13
11
  # Supported Method Parameters::
14
12
  # PWN::SAST::TypeScriptTypeJuggling.scan(
15
13
  # dir_path: 'optional path to dir defaults to .'
@@ -19,102 +17,25 @@ module PWN
19
17
  public_class_method def self.scan(opts = {})
20
18
  dir_path = opts[:dir_path]
21
19
  git_repo_root_uri = opts[:git_repo_root_uri].to_s.scrub
22
- result_arr = []
23
- ai_introspection = PWN::Env[:ai][:introspection]
24
- logger_results = "AI Introspection => #{ai_introspection} => "
25
-
26
- PWN::Plugins::FileFu.recurse_in_dir(dir_path: dir_path) do |entry|
27
- if (File.file?(entry) && File.basename(entry) !~ /^pwn.+(html|json|db)$/ && File.basename(entry) !~ /\.JS-BEAUTIFIED$/) && File.extname(entry).include?('.ts') && entry !~ /test/i
28
- line_no_and_contents_arr = []
29
- entry_beautified = false
30
-
31
- if File.extname(entry) == '.js' && (`wc -l #{entry}`.split.first.to_i < 20 || entry.include?('.min.js') || entry.include?('-all.js'))
32
- js_beautify = `js-beautify #{entry} > #{entry}.JS-BEAUTIFIED 2> /dev/null`.to_s.scrub
33
- entry = "#{entry}.JS-BEAUTIFIED"
34
- entry_beautified = true
35
- end
36
-
37
- test_case_filter = "
38
- grep -Fn \
39
- -e '==' \
40
- -e '!=' #{entry} 2>/dev/null | \
41
- grep -v \
42
- -e '===' \
43
- -e '!=='
44
- "
45
-
46
- str = `#{test_case_filter}`.to_s.scrub
47
20
 
48
- if str.to_s.empty?
49
- # If str length is >= 64 KB do not include results. (Due to Mongo Document Size Restrictions)
50
- logger_results = "#{logger_results}~" # Catching bugs is good :)
51
- else
52
- str = "1:Result larger than 64KB -> Size: #{str.to_s.length}. Please click the \"Path\" link for more details." if str.to_s.length >= 64_000
53
-
54
- hash_line = {
55
- timestamp: Time.now.strftime('%Y-%m-%d %H:%M:%S.%9N %z').to_s,
56
- security_references: security_references,
57
- filename: { git_repo_root_uri: git_repo_root_uri, entry: entry },
58
- line_no_and_contents: '',
59
- raw_content: str,
60
- test_case_filter: test_case_filter
61
- }
62
-
63
- # COMMMENT: Must be a better way to implement this (regex is kinda funky)
64
- line_contents_split = str.split(/^(\d{1,}):|\n(\d{1,}):/)[1..-1]
65
- line_no_count = line_contents_split.length # This should always be an even number
66
- current_count = 0
67
- while line_no_count > current_count
68
- line_no = line_contents_split[current_count]
69
- contents = line_contents_split[current_count + 1]
70
- if Dir.exist?('.git')
71
- repo_root = '.'
72
-
73
- author = PWN::Plugins::Git.get_author(
74
- repo_root: repo_root,
75
- from_line: line_no,
76
- to_line: line_no,
77
- target_file: entry,
78
- entry_beautified: entry_beautified
79
- )
80
- end
81
- author ||= 'N/A'
82
-
83
- ai_analysis = nil
84
- if ai_introspection
85
- request = {
86
- scm_uri: "#{hash_line[:filename][:git_repo_root_uri]}/#{hash_line[:filename][:entry]}",
87
- line_no: line_no,
88
- source_code_snippet: contents
89
- }.to_json
90
- response = PWN::AI::Introspection.reflect(request: request)
91
- if response.is_a?(Hash)
92
- ai_analysis = response[:choices].last[:text] if response[:choices].last.keys.include?(:text)
93
- ai_analysis = response[:choices].last[:content] if response[:choices].last.keys.include?(:content)
94
- end
95
- end
21
+ test_case_filter = "
22
+ grep -Fn \
23
+ -e '==' \
24
+ -e '!=' {PWN_SAST_SRC_TARGET} 2>/dev/null | \
25
+ grep -v \
26
+ -e '===' \
27
+ -e '!=='
28
+ "
96
29
 
97
- hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
98
- line_no: line_no,
99
- contents: contents,
100
- author: author,
101
- ai_analysis: ai_analysis
102
- )
30
+ include_extensions = %w[.ts .tsx .mts .cts .d.ts .d.mts .d.cts .js .mjs .cjs .map .tsbuildinfo]
103
31
 
104
- current_count += 2
105
- end
106
- result_arr.push(hash_line)
107
- logger_results = "#{logger_results}x" # Seeing progress is good :)
108
- end
109
- end
110
- end
111
- logger_banner = "http://#{Socket.gethostname}:8808/doc_root/pwn-#{PWN::VERSION.to_s.scrub}/#{to_s.scrub.gsub('::', '/')}.html"
112
- if logger_results.empty?
113
- @@logger.info("#{logger_banner}: No files applicable to this test case.\n")
114
- else
115
- @@logger.info("#{logger_banner} => #{logger_results}complete.\n")
116
- end
117
- result_arr
32
+ PWN::SAST::TestCaseEngine.execute(
33
+ test_case_filter: test_case_filter,
34
+ security_references: security_references,
35
+ dir_path: dir_path,
36
+ include_extensions: include_extensions,
37
+ git_repo_root_uri: git_repo_root_uri
38
+ )
118
39
  rescue StandardError => e
119
40
  raise e
120
41
  end