site-inspector 1.0.2 → 2.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +3 -0
  6. data/Guardfile +8 -0
  7. data/README.md +175 -0
  8. data/Rakefile +8 -0
  9. data/bin/site-inspector +48 -21
  10. data/lib/site-inspector.rb +38 -613
  11. data/lib/site-inspector/cache.rb +9 -52
  12. data/lib/site-inspector/checks/check.rb +41 -0
  13. data/lib/site-inspector/checks/content.rb +67 -0
  14. data/lib/site-inspector/checks/dns.rb +129 -0
  15. data/lib/site-inspector/checks/headers.rb +83 -0
  16. data/lib/site-inspector/checks/hsts.rb +78 -0
  17. data/lib/site-inspector/checks/https.rb +40 -0
  18. data/lib/site-inspector/checks/sniffer.rb +42 -0
  19. data/lib/site-inspector/disk_cache.rb +38 -0
  20. data/lib/site-inspector/domain.rb +248 -0
  21. data/lib/site-inspector/endpoint.rb +200 -0
  22. data/lib/site-inspector/rails_cache.rb +11 -0
  23. data/lib/site-inspector/version.rb +3 -0
  24. data/script/bootstrap +1 -0
  25. data/script/cibuild +7 -0
  26. data/script/console +1 -0
  27. data/script/release +38 -0
  28. data/site-inspector.gemspec +33 -0
  29. data/spec/checks/site_inspector_endpoint_check_spec.rb +34 -0
  30. data/spec/checks/site_inspector_endpoint_content_spec.rb +89 -0
  31. data/spec/checks/site_inspector_endpoint_dns_spec.rb +167 -0
  32. data/spec/checks/site_inspector_endpoint_headers_spec.rb +74 -0
  33. data/spec/checks/site_inspector_endpoint_hsts_spec.rb +91 -0
  34. data/spec/checks/site_inspector_endpoint_https_spec.rb +48 -0
  35. data/spec/checks/site_inspector_endpoint_sniffer_spec.rb +52 -0
  36. data/spec/site_inspector_cache_spec.rb +13 -0
  37. data/spec/site_inspector_disc_cache_spec.rb +31 -0
  38. data/spec/site_inspector_domain_spec.rb +252 -0
  39. data/spec/site_inspector_endpoint_spec.rb +224 -0
  40. data/spec/site_inspector_spec.rb +46 -0
  41. data/spec/spec_helper.rb +17 -0
  42. metadata +75 -57
  43. data/lib/site-inspector/compliance.rb +0 -19
  44. data/lib/site-inspector/dns.rb +0 -92
  45. data/lib/site-inspector/headers.rb +0 -59
  46. data/lib/site-inspector/sniffer.rb +0 -26
@@ -1,19 +0,0 @@
1
- class SiteInspector
2
-
3
- def path_exists?(path)
4
- url = URI.join uri, path
5
- Typhoeus::Request.get(url, followlocation: true, timeout: 10).success?
6
- end
7
-
8
- def slash_data?
9
- @slash_data ||= path_exists?("/data")
10
- end
11
-
12
- def slash_developer?
13
- @slash_developer ||= (path_exists?("/developer") || path_exists?("/developers"))
14
- end
15
-
16
- def data_dot_json?
17
- @data_dot_json ||= path_exists?("/data.json")
18
- end
19
- end
@@ -1,92 +0,0 @@
1
- class SiteInspector
2
-
3
- def resolver
4
- require "dnsruby"
5
- @resolver ||= begin
6
- resolver = Dnsruby::Resolver.new
7
- resolver.config.nameserver = ["8.8.8.8", "8.8.4.4"]
8
- resolver
9
- end
10
- end
11
-
12
- def query(type="ANY")
13
- resolver.query(domain.to_s, type).answer
14
- rescue
15
- []
16
- end
17
-
18
- def dns
19
- @dns ||= query
20
- end
21
-
22
- def has_record?(type)
23
- dns.any? { |record| record.type == type } || query(type).count != 0
24
- end
25
-
26
- def dnssec?
27
- @dnssec ||= has_record? "DNSKEY"
28
- end
29
-
30
- def ipv6?
31
- @ipv6 ||= has_record? "AAAA"
32
- end
33
-
34
- def detect_by_hostname(type)
35
-
36
- haystack = SiteInspector.load_data(type)
37
- needle = haystack.find { |name, domain|
38
- cnames.any? { |cname|
39
- domain == cname.tld || domain == "#{cname.sld}.#{cname.tld}"
40
- }
41
- }
42
-
43
- return needle[0] if needle
44
- return false unless hostname
45
-
46
- needle = haystack.find { |name, domain|
47
- domain == hostname.tld || domain == "#{hostname.sld}.#{hostname.tld}"
48
- }
49
-
50
- needle ? needle[0] : false
51
- end
52
-
53
- def cdn
54
- detect_by_hostname "cdn"
55
- end
56
-
57
- def cdn?
58
- !!cdn
59
- end
60
-
61
- def cloud_provider
62
- detect_by_hostname "cloud"
63
- end
64
-
65
- def cloud?
66
- !!cloud_provider
67
- end
68
-
69
- def google_apps?
70
- @google ||= dns.any? do |record|
71
- record.type == "MX" && record.exchange =~ /google(mail)?\.com\.?$/
72
- end
73
- end
74
-
75
- def ip
76
- require 'resolv'
77
- @ip ||= Resolv.getaddress domain.to_s
78
- rescue Resolv::ResolvError
79
- nil
80
- end
81
-
82
- def hostname
83
- require 'resolv'
84
- @hostname ||= PublicSuffix.parse(Resolv.getname(ip))
85
- rescue Exception => e
86
- nil
87
- end
88
-
89
- def cnames
90
- @cnames ||= dns.select {|record| record.type == "CNAME" }.map { |record| PublicSuffix.parse(record.cname.to_s) }
91
- end
92
- end
@@ -1,59 +0,0 @@
1
- class SiteInspector
2
-
3
- # cookies can have multiple set-cookie headers, so this detects
4
- # whether cookies are set, but not all their values.
5
- def has_cookies?
6
- !!headers["set-cookie"]
7
- end
8
-
9
- def strict_transport_security?
10
- !!strict_transport_security
11
- end
12
-
13
- def content_security_policy?
14
- !!content_security_policy
15
- end
16
-
17
- def click_jacking_protection?
18
- !!click_jacking_protection
19
- end
20
-
21
- # return the found header value
22
-
23
- def strict_transport_security
24
- headers["strict-transport-security"]
25
- end
26
-
27
- def content_security_policy
28
- headers["content-security-policy"]
29
- end
30
-
31
- def click_jacking_protection
32
- headers["x-frame-options"]
33
- end
34
-
35
- def server
36
- headers["server"]
37
- end
38
-
39
- def xss_protection
40
- headers["x-xss-protection"]
41
- end
42
-
43
- # more specific checks than presence of headers
44
- def xss_protection?
45
- xss_protection == "1; mode=block"
46
- end
47
-
48
- def secure_cookies?
49
- return false if !has_cookies?
50
- cookie = headers["set-cookie"]
51
- cookie = cookie.first if cookie.is_a?(Array)
52
- !!(cookie =~ /(; secure.*; httponly|; httponly.*; secure)/i)
53
- end
54
-
55
- # Returns an array of hashes of downcased key/value header pairs (or an empty hash)
56
- def headers
57
- @headers ||= response ? Hash[response.headers.map{ |k,v| [k.downcase,v] }] : {}
58
- end
59
- end
@@ -1,26 +0,0 @@
1
- class SiteInspector
2
- def sniff(type)
3
- require 'sniffles'
4
- results = Sniffles.sniff(body, type).select { |name, meta| meta[:found] == true }
5
- results.each { |name, result| result.delete :found} if results
6
- results
7
- rescue
8
- nil
9
- end
10
-
11
- def cms
12
- sniff :cms
13
- end
14
-
15
- def analytics
16
- sniff :analytics
17
- end
18
-
19
- def javascript
20
- sniff :javascript
21
- end
22
-
23
- def advertising
24
- sniff :advertising
25
- end
26
- end