codesake-dawn 0.60 → 0.70
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.
- data/.gitignore +1 -0
- data/Competitive_matrix.md +18 -4
- data/README.md +26 -44
- data/Roadmap.md +25 -11
- data/bin/dawn +104 -34
- data/{codesake_dawn.gemspec → codesake-dawn.gemspec} +5 -0
- data/features/dawn_complains_about_an_incorrect_command_line.feature +2 -2
- data/features/dawn_scan_a_secure_sinatra_app.feature +4 -4
- data/features/dawn_scan_a_vulnerable_sinatra_app.feature +36 -0
- data/features/step_definition/dawn_steps.rb +8 -2
- data/lib/codesake-dawn.rb +1 -0
- data/lib/codesake/dawn/core.rb +22 -0
- data/lib/codesake/dawn/engine.rb +66 -1
- data/lib/codesake/dawn/kb/cve_2011_0447.rb +30 -0
- data/lib/codesake/dawn/kb/cve_2011_2197.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_2932.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2011_3186.rb +31 -0
- data/lib/codesake/dawn/kb/cve_2012_1099.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_1241.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_2140.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_3463.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_3464.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_4464.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_4466.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_4481.rb +28 -0
- data/lib/codesake/dawn/kb/cve_2012_5370.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_5371.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2012_6134.rb +29 -0
- data/lib/codesake/dawn/kb/cve_2013_0333.rb +0 -3
- data/lib/codesake/dawn/kb/cve_2013_1821.rb +1 -1
- data/lib/codesake/dawn/kb/pattern_match_check.rb +4 -3
- data/lib/codesake/dawn/kb/ruby_version_check.rb +14 -4
- data/lib/codesake/dawn/knowledge_base.rb +30 -0
- data/lib/codesake/dawn/sinatra.rb +105 -0
- data/lib/codesake/dawn/version.rb +1 -1
- data/spec/lib/dawn/codesake_knowledgebase_spec.rb +87 -0
- data/spec/lib/dawn/codesake_sinatra_engine_spec.rb +44 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/support/sinatra-vulnerable/application.rb +6 -0
- data/spec/support/sinatra-vulnerable/disabled.png +0 -0
- data/spec/support/sinatra-vulnerable/views/xss.haml +3 -0
- metadata +91 -15
- data/spec/support/hello_world_3.0.19/.gitignore +0 -4
- data/spec/support/hello_world_3.1.0/.gitignore +0 -5
- data/spec/support/hello_world_3.2.13/.gitignore +0 -15
- data/spec/support/sinatra-safe/.gitignore +0 -6
- data/spec/support/sinatra-vulnerable/.gitignore +0 -6
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_3463
|
6
|
+
include DependencyCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="Cross-site scripting (XSS) vulnerability in actionpack/lib/action_view/helpers/form_tag_helper.rb in Ruby on Rails 3.x before 3.0.17, 3.1.x before 3.1.8, and 3.2.x before 3.2.8 allows remote attackers to inject arbitrary web script or HTML via the prompt field to the select_tag helper."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-3463",
|
12
|
+
:cvss=>"AV:N/AC:M/Au:N/C:N/I:P/A:N",
|
13
|
+
:release_date => Date.new(2012, 8, 10),
|
14
|
+
:cwe=>"79",
|
15
|
+
:owasp=>"A3",
|
16
|
+
:applies=>["rails"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade rails version at least to 3.0.17, 3.1.8 or 3.2.8. As a general rule, using the latest stable rails version is recommended.",
|
20
|
+
:aux_links=>["https://groups.google.com/group/rubyonrails-security/msg/961e18e514527078?dmode=source&output=gplain"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_dependencies = [{:name=>"rails", :version=>['3.0.17', '3.1.8', '3.2.8']}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_3464
|
6
|
+
include DependencyCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message = "Cross-site scripting (XSS) vulnerability in activesupport/lib/active_support/core_ext/string/output_safety.rb in Ruby on Rails before 3.0.17, 3.1.x before 3.1.8, and 3.2.x before 3.2.8 might allow remote attackers to inject arbitrary web script or HTML via vectors involving a ' (quote) character."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-3464",
|
12
|
+
:cvss=>"AV:N/AC:M/Au:N/C:N/I:P/A:N",
|
13
|
+
:release_date => Date.new(2012, 8, 10),
|
14
|
+
:cwe=>"79",
|
15
|
+
:owasp=>"A3",
|
16
|
+
:applies=>["rails"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade rails version at least to 3.0.17, 3.1.8 or 3.2.8. As a general rule, using the latest stable rails version is recommended.",
|
20
|
+
:aux_links=>["https://groups.google.com/group/rubyonrails-security/msg/8f1bbe1cef8c6caf?dmode=source&output=gplain"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_dependencies = [{:name=>"rails", :version=>['3.0.17', '3.1.8', '3.2.8']}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_4464
|
6
|
+
include RubyVersionCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message = "Ruby 1.9.3 before patchlevel 286 and 2.0 before revision r37068 allows context-dependent attackers to bypass safe-level restrictions and modify untainted strings via the (1) exc_to_s or (2) name_err_to_s API function, which marks the string as tainted, a different vulnerability than CVE-2012-4466. NOTE: this issue might exist because of a CVE-2011-1005 regression."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-4464",
|
12
|
+
:cvss=>"AV:N/AC:L/Au:N/C:N/I:P/A:N",
|
13
|
+
:release_date => Date.new(2013, 4, 25),
|
14
|
+
:cwe=>"264",
|
15
|
+
:owasp=>"A9",
|
16
|
+
:applies=>["rails", "sinatra", "padrino"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade ruby interpreter to 1.9.3-p286 or 2.0.0-p195 or latest version available",
|
20
|
+
:aux_links=>["ihttp://www.ruby-lang.org/en/news/2012/10/12/cve-2012-4464-cve-2012-4466/"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_rubies = [{:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p286"}, {:engine=>"ruby", :version=>"2.0.0", :patchlevel=>"p195"}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_4466
|
6
|
+
include RubyVersionCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="Ruby 1.8.7 before patchlevel 371, 1.9.3 before patchlevel 286, and 2.0 before revision r37068 allows context-dependent attackers to bypass safe-level restrictions and modify untainted strings via the name_err_mesg_to_str API function, which marks the string as tainted, a different vulnerability than CVE-2011-1005."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-4466",
|
12
|
+
:cvss=>"AV:N/AC:L/Au:N/C:N/I:P/A:N",
|
13
|
+
:release_date => Date.new(2013, 4, 25),
|
14
|
+
:cwe=>"264",
|
15
|
+
:owasp=>"A9",
|
16
|
+
:applies=>["rails", "sinatra", "padrino"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade ruby interpreter to 1.8.7-p371, 1.9.3-p286 or 2.0.0-p195 or latest version available",
|
20
|
+
:aux_links=>["http://www.ruby-lang.org/en/news/2012/10/12/cve-2012-4464-cve-2012-4466/"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_rubies = [{:engine=>"ruby", :version=>"1.8.7", :patchlevel=>"p371"}, {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p286"}, {:engine=>"ruby", :version=>"2.0.0", :patchlevel=>"p195"}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-31
|
5
|
+
class CVE_2012_4481
|
6
|
+
include RubyVersionCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="The safe-level feature in Ruby 1.8.7 allows context-dependent attackers to modify strings via the NameError#to_s method when operating on Ruby objects. NOTE: this issue is due to an incomplete fix for CVE-2011-1005."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-4481",
|
12
|
+
:cvss=>"AV:N/AC:M/Au:N/C:N/I:P/A:N",
|
13
|
+
:release_date => Date.new(2013, 5, 2),
|
14
|
+
:cwe=>"264",
|
15
|
+
:owasp=>"A9",
|
16
|
+
:applies=>["rails", "sinatra", "padrino"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade ruby interpreter to 1.9.3 or 2.0.0 or latest version available",
|
20
|
+
:aux_links=>["https://bugzilla.redhat.com/show_bug.cgi?id=863484"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_rubies = [{:engine=>"ruby", :version=>"1.8.7", :patchlevel=>"p9999"}]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_5370
|
6
|
+
include RubyVersionCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="JRuby computes hash values without properly restricting the ability to trigger hash collisions predictably, which allows context-dependent attackers to cause a denial of service (CPU consumption) via crafted input to an application that maintains a hash table, as demonstrated by a universal multicollision attack against the MurmurHash2 algorithm, a different vulnerability than CVE-2011-4838."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-5370",
|
12
|
+
:cvss=>"AV:N/AC:L/Au:N/C:N/I:N/A:P",
|
13
|
+
:release_date => Date.new(2012, 11, 28),
|
14
|
+
:cwe=>"310",
|
15
|
+
:owasp=>"A9",
|
16
|
+
:applies=>["rails", "sinatra", "padrino"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"At the moment we're writing this (May 2013) there is no mitigation against this vulnerability. You must consider changing your hashing algorithm",
|
20
|
+
:aux_links=>["https://bugzilla.redhat.com/show_bug.cgi?id=880671"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_rubies = [{:engine=>"jruby", :version=>"999.999.999", :patchlevel=>"p999"}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-30
|
5
|
+
class CVE_2012_5371
|
6
|
+
include RubyVersionCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="Ruby (aka CRuby) 1.9 before 1.9.3-p327 and 2.0 before r37575 computes hash values without properly restricting the ability to trigger hash collisions predictably, which allows context-dependent attackers to cause a denial of service (CPU consumption) via crafted input to an application that maintains a hash table, as demonstrated by a universal multicollision attack against a variant of the MurmurHash2 algorithm, a different vulnerability than CVE-2011-4815."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-5371",
|
12
|
+
:cvss=>"AV:N/AC:L/Au:N/C:N/I:N/A:P",
|
13
|
+
:release_date => Date.new(2012, 11, 28),
|
14
|
+
:cwe=>"310",
|
15
|
+
:owasp=>"A9",
|
16
|
+
:applies=>["rails", "sinatra", "padrino"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::RUBY_VERSION_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade ruby interpreter to 1.9.3-p327 or 2.0.0-p195 or latest version available",
|
20
|
+
:aux_links=>["http://www.ruby-lang.org/en/news/2012/11/09/ruby19-hashdos-cve-2012-5371/"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_rubies = [{:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p327"}, {:engine=>"ruby", :version=>"2.0.0", :patchlevel=>"p195"}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codesake
|
2
|
+
module Dawn
|
3
|
+
module Kb
|
4
|
+
# Automatically created with rake on 2013-05-31
|
5
|
+
class CVE_2012_6134
|
6
|
+
include DependencyCheck
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
message="Cross-site request forgery (CSRF) vulnerability in the omniauth-oauth2 gem 1.1.1 and earlier for Ruby allows remote attackers to hijack the authentication of users for requests that modify session state."
|
10
|
+
super({
|
11
|
+
:name=>"CVE-2012-6134",
|
12
|
+
:cvss=>"AV:N/AC:M/Au:N/C:P/I:P/A:P",
|
13
|
+
:release_date => Date.new(2013, 4, 9),
|
14
|
+
:cwe=>"352",
|
15
|
+
:owasp=>"A8",
|
16
|
+
:applies=>["rails"],
|
17
|
+
:kind=>Codesake::Dawn::KnowledgeBase::DEPENDENCY_CHECK,
|
18
|
+
:message=>message,
|
19
|
+
:mitigation=>"Please upgrade omniauth-oauth2 version to the latest one",
|
20
|
+
:aux_links=>["https://github.com/intridea/omniauth-oauth2/pull/25"]
|
21
|
+
})
|
22
|
+
|
23
|
+
self.safe_dependencies = [{:name=>"omniauth-oauth2", :version=>['1.1.2']}]
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -20,7 +20,7 @@ module Codesake
|
|
20
20
|
:aux_links=>["http://www.ruby-lang.org/en/news/2013/02/22/rexml-dos-2013-02-22/"]
|
21
21
|
})
|
22
22
|
|
23
|
-
self.safe_rubies = [{:version=>"1.9.3", :patchlevel=>"p392"}, {:version=>"2.0.0", :patchlevel=>"p195"}]
|
23
|
+
self.safe_rubies = [{:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p392"}, {:engine=>"ruby", :version=>"2.0.0", :patchlevel=>"p195"}]
|
24
24
|
|
25
25
|
|
26
26
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require 'ptools'
|
2
|
+
|
2
3
|
module Codesake
|
3
4
|
module Dawn
|
4
5
|
module Kb
|
@@ -16,7 +17,8 @@ module Codesake
|
|
16
17
|
|
17
18
|
def vuln?
|
18
19
|
Dir.glob(File.join("#{root_dir}", "*")).each do |filename|
|
19
|
-
matches =
|
20
|
+
matches = []
|
21
|
+
matches = run(load_file(filename)) if File.exists?(filename) and File.file?(filename) and ! File.binary?(filename)
|
20
22
|
@evidences << {:filename=>filename, :matches=>matches} unless matches.empty?
|
21
23
|
end
|
22
24
|
return ! @evidences.empty?
|
@@ -29,7 +31,6 @@ module Codesake
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def load_file(filename)
|
32
|
-
return [] unless File.exists?(filename) and File.file?(filename)
|
33
34
|
|
34
35
|
f = File.open(filename)
|
35
36
|
lines = f.readlines
|
@@ -4,20 +4,24 @@ module Codesake
|
|
4
4
|
module RubyVersionCheck
|
5
5
|
include BasicCheck
|
6
6
|
|
7
|
-
# Array of hashes in the {:version=>"1.9.3", :patchlevel=>"p342"} form
|
7
|
+
# Array of hashes in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form
|
8
8
|
attr_accessor :safe_rubies
|
9
|
-
# Hash in the {:version=>"1.9.3", :patchlevel=>"p342"} form
|
9
|
+
# Hash in the {:engine=>"ruby", :version=>"1.9.3", :patchlevel=>"p342"} form
|
10
10
|
attr_accessor :detected_ruby
|
11
11
|
|
12
12
|
def vuln?
|
13
13
|
vv_a = []
|
14
14
|
vv_p = []
|
15
|
+
vv_e = []
|
15
16
|
vp = false
|
16
17
|
|
18
|
+
|
17
19
|
@safe_rubies.each do |ss|
|
20
|
+
vv_e << ss[:engine]
|
18
21
|
vv_a << ss[:version]
|
19
22
|
vv_p << ss[:patchlevel].split("p")[1].to_i
|
20
23
|
end
|
24
|
+
vengine = self.is_vulnerable_engine?(detected_ruby[:engine], vv_e)
|
21
25
|
vv = self.is_vulnerable_version?(detected_ruby[:version], vv_a)
|
22
26
|
|
23
27
|
# Since we have also the patch level a fixes version can be the same
|
@@ -25,10 +29,16 @@ module Codesake
|
|
25
29
|
ve = self.is_same_version?(detected_ruby[:version], vv_a) unless vv
|
26
30
|
vp = is_vulnerable_patchlevel?(detected_ruby[:patchlevel], vv_p) if ve
|
27
31
|
|
28
|
-
return true if vv
|
29
|
-
return (ve and vp)
|
32
|
+
return true if ( vv and vengine )
|
33
|
+
return (ve and vp and vengine )
|
30
34
|
end
|
31
35
|
|
36
|
+
def is_vulnerable_engine?(target, fixes = [])
|
37
|
+
fixes.each do |f|
|
38
|
+
return true if f == target
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
def is_same_version?(target, fixes = [])
|
33
43
|
fixes.each do |f|
|
34
44
|
return true if f == target
|
@@ -8,14 +8,29 @@ require "codesake/dawn/kb/ruby_version_check"
|
|
8
8
|
require "codesake/dawn/kb/not_revised_code"
|
9
9
|
|
10
10
|
# CVE - 2011
|
11
|
+
require "codesake/dawn/kb/cve_2011_0447"
|
12
|
+
require "codesake/dawn/kb/cve_2011_2197"
|
11
13
|
require "codesake/dawn/kb/cve_2011_2931"
|
14
|
+
require "codesake/dawn/kb/cve_2011_2932"
|
15
|
+
require "codesake/dawn/kb/cve_2011_3186"
|
12
16
|
|
13
17
|
# CVE - 2012
|
18
|
+
require "codesake/dawn/kb/cve_2012_1099"
|
19
|
+
require "codesake/dawn/kb/cve_2012_1241"
|
20
|
+
require "codesake/dawn/kb/cve_2012_2140"
|
14
21
|
require "codesake/dawn/kb/cve_2012_2660"
|
15
22
|
require "codesake/dawn/kb/cve_2012_2661"
|
16
23
|
require "codesake/dawn/kb/cve_2012_2694"
|
17
24
|
require "codesake/dawn/kb/cve_2012_2695"
|
25
|
+
require "codesake/dawn/kb/cve_2012_3463"
|
26
|
+
require "codesake/dawn/kb/cve_2012_3464"
|
18
27
|
require "codesake/dawn/kb/cve_2012_3465"
|
28
|
+
require "codesake/dawn/kb/cve_2012_4464"
|
29
|
+
require "codesake/dawn/kb/cve_2012_4466"
|
30
|
+
require "codesake/dawn/kb/cve_2012_4481"
|
31
|
+
require "codesake/dawn/kb/cve_2012_5370"
|
32
|
+
require "codesake/dawn/kb/cve_2012_5371"
|
33
|
+
require "codesake/dawn/kb/cve_2012_6134"
|
19
34
|
require "codesake/dawn/kb/cve_2012_6496"
|
20
35
|
require "codesake/dawn/kb/cve_2012_6497"
|
21
36
|
|
@@ -110,12 +125,27 @@ module Codesake
|
|
110
125
|
def self.load_security_checks
|
111
126
|
[
|
112
127
|
Codesake::Dawn::Kb::NotRevisedCode.new,
|
128
|
+
Codesake::Dawn::Kb::CVE_2011_0447.new,
|
129
|
+
Codesake::Dawn::Kb::CVE_2011_2197.new,
|
113
130
|
Codesake::Dawn::Kb::CVE_2011_2931.new,
|
131
|
+
Codesake::Dawn::Kb::CVE_2011_2932.new,
|
132
|
+
Codesake::Dawn::Kb::CVE_2011_3186.new,
|
133
|
+
Codesake::Dawn::Kb::CVE_2012_1099.new,
|
134
|
+
Codesake::Dawn::Kb::CVE_2012_1241.new,
|
135
|
+
Codesake::Dawn::Kb::CVE_2012_2140.new,
|
114
136
|
Codesake::Dawn::Kb::CVE_2012_2660.new,
|
115
137
|
Codesake::Dawn::Kb::CVE_2012_2661.new,
|
116
138
|
Codesake::Dawn::Kb::CVE_2012_2694.new,
|
117
139
|
Codesake::Dawn::Kb::CVE_2012_2695.new,
|
140
|
+
Codesake::Dawn::Kb::CVE_2012_3463.new,
|
141
|
+
Codesake::Dawn::Kb::CVE_2012_3464.new,
|
118
142
|
Codesake::Dawn::Kb::CVE_2012_3465.new,
|
143
|
+
Codesake::Dawn::Kb::CVE_2012_4464.new,
|
144
|
+
Codesake::Dawn::Kb::CVE_2012_4466.new,
|
145
|
+
Codesake::Dawn::Kb::CVE_2012_4481.new,
|
146
|
+
Codesake::Dawn::Kb::CVE_2012_5370.new,
|
147
|
+
Codesake::Dawn::Kb::CVE_2012_5371.new,
|
148
|
+
Codesake::Dawn::Kb::CVE_2012_6134.new,
|
119
149
|
Codesake::Dawn::Kb::CVE_2012_6496.new,
|
120
150
|
Codesake::Dawn::Kb::CVE_2012_6497.new,
|
121
151
|
Codesake::Dawn::Kb::CVE_2013_0155.new,
|
@@ -1,14 +1,119 @@
|
|
1
1
|
require "codesake/dawn/engine"
|
2
|
+
require 'ruby_parser'
|
2
3
|
|
3
4
|
module Codesake
|
4
5
|
module Dawn
|
5
6
|
class Sinatra
|
6
7
|
include Codesake::Dawn::Engine
|
7
8
|
|
9
|
+
attr_reader :sinks
|
10
|
+
attr_reader :appname
|
11
|
+
|
8
12
|
def initialize(dir=nil)
|
9
13
|
super(dir, "sinatra")
|
14
|
+
@appname = detect_appname(self.target)
|
15
|
+
error! if self.appname == ""
|
16
|
+
@sinks = detect_sinks(self.appname) unless self.appname == ""
|
17
|
+
@reflected_xss = detect_reflected_xss unless self.appname == ""
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: appname should be hopefully autodetect from config.ru
|
21
|
+
def detect_appname(target)
|
22
|
+
return "app.rb" if File.exist?(File.join(self.target, "app.rb"))
|
23
|
+
return "application.rb" if File.exist?(File.join(self.target, "application.rb"))
|
24
|
+
file_array = Dir.glob(File.join("#{target}", "*.rb"))
|
25
|
+
return file_array[0] if ! file_array.nil? and file_array.count == 1
|
26
|
+
return "" # gracefully failure
|
27
|
+
end
|
28
|
+
|
29
|
+
def detect_reflected_xss
|
30
|
+
ret = []
|
31
|
+
@views.each do |v|
|
32
|
+
view_content = File.read(v[:filename])
|
33
|
+
@sinks.each do |sink|
|
34
|
+
ret << sink if view_content.match(sink[:sink_name])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
|
40
|
+
def detect_sinks(appname=nil)
|
41
|
+
ret = []
|
42
|
+
appname = "app.rb" if appname.nil? and self.appname == ""
|
43
|
+
app_rb = File.readlines(File.join(self.target, appname)) if File.exist?(File.join(self.target, appname))
|
44
|
+
return [] if app_rb.nil?
|
45
|
+
|
46
|
+
parser = RubyParser.new
|
47
|
+
|
48
|
+
app_rb.each_with_index do |line, i|
|
49
|
+
line = line.chomp
|
50
|
+
|
51
|
+
unless line.match(/params/).nil?
|
52
|
+
|
53
|
+
begin
|
54
|
+
t = parser.parse(line)
|
55
|
+
|
56
|
+
# a[1] = params["foo"]
|
57
|
+
#
|
58
|
+
if (! t.nil? and t.sexp_type == :attrasgn)
|
59
|
+
body = t.sexp_body.to_a
|
60
|
+
|
61
|
+
if is_assignement_from_params?(body, :attrasgn)
|
62
|
+
|
63
|
+
if body[0][0] == :call
|
64
|
+
sink_name=body[0][2].to_s unless body[1].to_s == "[]="
|
65
|
+
sink_name="#{body[2].to_a[1].to_s}" if body[1].to_s == "[]=" # the sink is assigned to an Array
|
66
|
+
|
67
|
+
sink_source = "#{body[3].to_a[1][2].to_s}[#{body[3].to_a[3][1].to_s}]"
|
68
|
+
|
69
|
+
ret << {:sink_name=>sink_name, :sink_kind=>:params, :sink_line=>i+1, :sink_source=>sink_source}
|
70
|
+
end
|
71
|
+
if body[0][0] == :ivar
|
72
|
+
sink_name=body[0][1].to_s
|
73
|
+
sink_pos=body[2][1].to_i
|
74
|
+
sink_source=body[3][3][1]
|
75
|
+
|
76
|
+
ret << {:sink_name=>sink_name, :sink_kind=>:params, :sink_line=>i+1, :sink_source=>sink_source}
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# a = params["foo"]
|
83
|
+
if (! t.nil? and t.sexp_type == :iasgn)
|
84
|
+
body = t.sexp_body.to_a
|
85
|
+
if is_assignement_from_params?(body, :iasgn)
|
86
|
+
sink_name = body[0].to_s
|
87
|
+
sink_source = "#{body[1][3][1].to_s}"
|
88
|
+
ret << {:sink_name=>sink_name, :sink_kind=>:params, :sink_line=>i+1, :sink_source=>sink_source }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
rescue Racc::ParseError => e
|
92
|
+
# TODO: we must pass logger instance to engines if we want some error message
|
93
|
+
# For now... silently discard parse errors
|
94
|
+
return []
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
ret
|
10
101
|
end
|
11
102
|
|
103
|
+
|
104
|
+
def is_assignement_from_params?(body, kind)
|
105
|
+
return ( ! body[3].nil? and body[3].to_a[1][2].to_s == "params") if kind == :attrasgn
|
106
|
+
return ( ! body[1].nil? and ! body[1][1].nil? and body[1][1][2].to_s == "params") if kind == :iasgn
|
107
|
+
end
|
108
|
+
|
109
|
+
def detect_views
|
110
|
+
build_view_array(File.join(self.target, "views")) if File.exist?(File.join(self.target, "views"))
|
111
|
+
end
|
112
|
+
|
113
|
+
# e = Haml::Engine.new(File.read(template))
|
114
|
+
# e.precompiled and grep for format_script
|
115
|
+
|
116
|
+
|
12
117
|
end
|
13
118
|
end
|
14
119
|
end
|