codesake-dawn 0.60 → 0.70
Sign up to get free protection for your applications and to get access to all the features.
- 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
|