lib/scanner/generic.rb in yawast-0.7.0.beta1 vs lib/scanner/generic.rb in yawast-0.7.0.beta2
- old
+ new
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require 'ipaddr_extensions'
require 'json'
require 'public_suffix'
module Yawast
@@ -7,11 +9,11 @@
class Generic
def self.head_info(head, uri)
begin
server = ''
powered_by = ''
- cookies = Array.new
+ cookies = []
pingback = ''
frame_options = ''
content_options = ''
csp = ''
backend_server = ''
@@ -24,25 +26,25 @@
Yawast::Utilities.puts_info 'HEAD:'
head.each do |k, v|
Yawast::Utilities.puts_info "\t\t#{k}: #{v}"
Yawast::Shared::Output.log_value 'http', 'head', k, v
- server = v if k.downcase == 'server'
- powered_by = v if k.downcase == 'x-powered-by'
- pingback = v if k.downcase == 'x-pingback'
- frame_options = v if k.downcase == 'x-frame-options'
- content_options = v if k.downcase == 'x-content-type-options'
- csp = v if k.downcase == 'content-security-policy'
- backend_server = v if k.downcase == 'x-backend-server'
- runtime = v if k.downcase == 'x-runtime'
- xss_protection = v if k.downcase == 'x-xss-protection'
- via = v if k.downcase == 'via'
- hpkp = v if k.downcase == 'public-key-pins'
- acao = v if k.downcase == 'access-control-allow-origin'
+ server = v if k.casecmp('server').zero?
+ powered_by = v if k.casecmp('x-powered-by').zero?
+ pingback = v if k.casecmp('x-pingback').zero?
+ frame_options = v if k.casecmp('x-frame-options').zero?
+ content_options = v if k.casecmp('x-content-type-options').zero?
+ csp = v if k.casecmp('content-security-policy').zero?
+ backend_server = v if k.casecmp('x-backend-server').zero?
+ runtime = v if k.casecmp('x-runtime').zero?
+ xss_protection = v if k.casecmp('x-xss-protection').zero?
+ via = v if k.casecmp('via').zero?
+ hpkp = v if k.casecmp('public-key-pins').zero?
+ acao = v if k.casecmp('access-control-allow-origin').zero?
- if k.downcase == 'set-cookie'
- #this chunk of magic manages to properly split cookies, when multiple are sent together
+ if k.casecmp('set-cookie').zero?
+ # this chunk of magic manages to properly split cookies, when multiple are sent together
v.gsub(/(,([^;,]*=)|,$)/) { "\r\n#{$2}" }.split(/\r\n/).each do |c|
cookies.push(c)
Yawast::Shared::Output.log_append_value 'http', 'head', 'cookies', c
end
@@ -50,53 +52,43 @@
end
puts ''
if server != ''
Yawast::Scanner::Plugins::Servers::Apache.check_banner(server)
- Yawast::Scanner::Php.check_banner(server)
+ Yawast::Scanner::Plugins::Servers::Generic.check_banner_php(server)
Yawast::Scanner::Plugins::Servers::Iis.check_banner(server)
Yawast::Scanner::Plugins::Servers::Nginx.check_banner(server)
Yawast::Scanner::Plugins::Servers::Python.check_banner(server)
- if server == 'cloudflare-nginx'
+ if server == 'cloudflare'
Yawast::Utilities.puts_info 'NOTE: Server appears to be Cloudflare; WAF may be in place.'
puts
end
end
- if powered_by != ''
- Yawast::Utilities.puts_warn "X-Powered-By Header Present: #{powered_by}"
- end
+ Yawast::Utilities.puts_warn "X-Powered-By Header Present: #{powered_by}" if powered_by != ''
- if xss_protection == '0'
- Yawast::Utilities.puts_warn 'X-XSS-Protection Disabled Header Present'
- end
+ Yawast::Utilities.puts_warn 'X-XSS-Protection Disabled Header Present' if xss_protection == '0'
- unless pingback == ''
- Yawast::Utilities.puts_info "X-Pingback Header Present: #{pingback}"
- end
+ Yawast::Utilities.puts_info "X-Pingback Header Present: #{pingback}" unless pingback == ''
unless runtime == ''
if runtime.is_number?
Yawast::Utilities.puts_warn 'X-Runtime Header Present; likely indicates a RoR application'
else
Yawast::Utilities.puts_warn "X-Runtime Header Present: #{runtime}"
end
end
- unless backend_server == ''
- Yawast::Utilities.puts_warn "X-Backend-Server Header Present: #{backend_server}"
- end
+ Yawast::Utilities.puts_warn "X-Backend-Server Header Present: #{backend_server}" unless backend_server == ''
- unless via == ''
- Yawast::Utilities.puts_warn "Via Header Present: #{via}"
- end
+ Yawast::Utilities.puts_warn "Via Header Present: #{via}" unless via == ''
if frame_options == ''
Yawast::Utilities.puts_warn 'X-Frame-Options Header Not Present'
else
- if frame_options.downcase == 'allow'
+ if frame_options.casecmp('allow').zero?
Yawast::Utilities.puts_vuln "X-Frame-Options Header: #{frame_options}"
else
Yawast::Utilities.puts_info "X-Frame-Options Header: #{frame_options}"
end
end
@@ -105,21 +97,15 @@
Yawast::Utilities.puts_warn 'X-Content-Type-Options Header Not Present'
else
Yawast::Utilities.puts_info "X-Content-Type-Options Header: #{content_options}"
end
- if csp == ''
- Yawast::Utilities.puts_warn 'Content-Security-Policy Header Not Present'
- end
+ Yawast::Utilities.puts_warn 'Content-Security-Policy Header Not Present' if csp == ''
- if hpkp == ''
- Yawast::Utilities.puts_warn 'Public-Key-Pins Header Not Present'
- end
+ Yawast::Utilities.puts_warn 'Public-Key-Pins Header Not Present' if hpkp == ''
- if acao == '*'
- Yawast::Utilities.puts_warn 'Access-Control-Allow-Origin: Unrestricted'
- end
+ Yawast::Utilities.puts_warn 'Access-Control-Allow-Origin: Unrestricted' if acao == '*'
puts ''
unless cookies.empty?
Yawast::Utilities.puts_info 'Cookies:'
@@ -127,120 +113,37 @@
cookies.each do |val|
Yawast::Utilities.puts_info "\t\t#{val.strip}"
elements = val.strip.split(';')
- #check for secure cookies
+ # check for secure cookies
if elements.include?(' Secure') || elements.include?(' secure')
if uri.scheme != 'https'
Yawast::Utilities.puts_warn "\t\t\tCookie with Secure flag sent over non-HTTPS connection"
end
else
Yawast::Utilities.puts_warn "\t\t\tCookie missing Secure flag"
end
- #check for HttpOnly cookies
+ # check for HttpOnly cookies
unless elements.include?(' HttpOnly') || elements.include?(' httponly')
Yawast::Utilities.puts_warn "\t\t\tCookie missing HttpOnly flag"
end
- #check for SameSite cookies
+ # check for SameSite cookies
unless elements.include?(' SameSite') || elements.include?(' samesite')
Yawast::Utilities.puts_warn "\t\t\tCookie missing SameSite flag"
end
end
puts ''
end
puts ''
- rescue => e
+ rescue => e # rubocop:disable Style/RescueStandardError
Yawast::Utilities.puts_error "Error getting head information: #{e.message}"
raise
end
end
-
- def self.check_options(uri)
- begin
- req = Yawast::Shared::Http.get_http(uri)
- req.use_ssl = uri.scheme == 'https'
- headers = Yawast::Shared::Http.get_headers
- res = req.request(Options.new('/', headers))
-
- if res['Public'] != nil
- Yawast::Utilities.puts_info "Public HTTP Verbs (OPTIONS): #{res['Public']}"
- Yawast::Shared::Output.log_value 'http', 'options', 'public', res['Public']
-
- puts ''
- end
- if res['Allow'] != nil
- Yawast::Utilities.puts_info "Allow HTTP Verbs (OPTIONS): #{res['Allow']}"
- Yawast::Shared::Output.log_value 'http', 'options', 'allow', res['Allow']
-
- puts ''
- end
- end
- end
-
- def self.check_trace(uri)
- begin
- req = Yawast::Shared::Http.get_http(uri)
- req.use_ssl = uri.scheme == 'https'
- headers = Yawast::Shared::Http.get_headers
- res = req.request(Trace.new('/', headers))
-
- if res.body.include?('TRACE / HTTP/1.1') && res.code == '200'
- Yawast::Utilities.puts_warn 'HTTP TRACE Enabled'
- puts "\t\t\"curl -X TRACE #{uri}\""
-
- puts ''
- end
-
- Yawast::Shared::Output.log_value 'http', 'trace', 'raw', res.body
- Yawast::Shared::Output.log_value 'http', 'trace', 'code', res.code
- end
- end
-
- def self.check_propfind(uri)
- begin
- req = Yawast::Shared::Http.get_http(uri)
- req.use_ssl = uri.scheme == 'https'
- headers = Yawast::Shared::Http.get_headers
- res = req.request(Propfind.new('/', headers))
-
- if res.code.to_i <= 400 && res.body.length > 0 && res['Content-Type'] == 'text/xml'
- Yawast::Utilities.puts_warn 'Possible Info Disclosure: PROPFIND Enabled'
- puts "\t\t\"curl -X PROPFIND #{uri}\""
-
- puts ''
- end
-
- Yawast::Shared::Output.log_value 'http', 'propfind', 'raw', res.body
- Yawast::Shared::Output.log_value 'http', 'propfind', 'code', res.code
- Yawast::Shared::Output.log_value 'http', 'propfind', 'content-type', res['Content-Type']
- Yawast::Shared::Output.log_value 'http', 'propfind', 'length', res.body.length
- end
- end
- end
-
- #Custom class to allow using the PROPFIND verb
- class Propfind < Net::HTTPRequest
- METHOD = 'PROPFIND'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
- end
-
- #Custom class to allow using the OPTIONS verb
- class Options < Net::HTTPRequest
- METHOD = 'OPTIONS'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
- end
-
- #Custom class to allow using the TRACE verb
- class Trace < Net::HTTPRequest
- METHOD = 'TRACE'
- REQUEST_HAS_BODY = false
- RESPONSE_HAS_BODY = true
end
end
end