codesake 0.0.1 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,4 @@
1
1
  module Codesake
2
- VERSION = "0.0.1"
2
+ VERSION = "0.15.1"
3
+ CODENAME = "BluePint"
3
4
  end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe "codesake command line interface" do
4
+ before(:all) do
5
+ @cli = Codesake::Cli.new
6
+ end
7
+ it "has a parse method" do
8
+ @cli.should respond_to(:parse)
9
+ end
10
+
11
+ it "returns an empty has if no command line is given" do
12
+ @cli.parse(nil).should == {:vulnerabilities=>:all}
13
+ @cli.parse("").should == {:vulnerabilities=>:all}
14
+ end
15
+
16
+
17
+ it "understands --version flag" do
18
+ @cli.parse("--version").should == {:version=>true, :vulnerabilities=>:all}
19
+ end
20
+ it "understands --output flag" do
21
+ @cli.parse("-o file").should == {:output=>:file, :vulnerabilities=>:all}
22
+ @cli.parse("-o json").should == {:output=>:json, :vulnerabilities=>:all}
23
+ @cli.parse("-o db").should == {:output=>:db, :vulnerabilities=>:all}
24
+
25
+ end
26
+ it "understands --verbose flag" do
27
+ @cli.parse("--verbose").should == {:verbose=>true, :vulnerabilities=>:all}
28
+ @cli.parse("-V").should == {:verbose=>true, :vulnerabilities=>:all}
29
+ end
30
+
31
+ it "saves targets" do
32
+ @cli.parse("file1")
33
+ @cli.targets.should == [{:target=>"file1", :valid=>false}]
34
+ @cli.parse("file1 file2")
35
+ @cli.targets.should == [{:target=>"file1", :valid=>false}, {:target=>"file2", :valid=>false}]
36
+ @cli.parse("Gemfile")
37
+ @cli.targets.should == [{:target=>"Gemfile", :valid=>true}]
38
+ end
39
+
40
+ it "the target should be either a file or a directory" do
41
+ @cli.is_good_target?("Gemfile").should be_true
42
+ @cli.is_good_target?("file1").should be_false
43
+ end
44
+ it "must produce a non nil option Hash" do
45
+ @cli.parse("").should_not be_nil
46
+ @cli.parse("-nonsense").should_not be_nil
47
+ @cli.parse("-v -h").should_not be_nil
48
+ @cli.parse("-j drift").should_not be_nil
49
+ end
50
+
51
+ it "understand --keys flag" do
52
+ ret = {:keywords => ["a","b","c"], :vulnerabilities=>:all}
53
+ @cli.parse("-k a,b,c").should == ret
54
+ end
55
+
56
+ it "understand --all-vulnerabilities" do
57
+ ret = {:vulnerabilities=>:all}
58
+ @cli.parse("-A").should == ret
59
+ end
60
+ it "understand --confirmed-vulnerabilities" do
61
+ ret = {:vulnerabilities=>:confirmed}
62
+ @cli.parse("-C").should == ret
63
+ end
64
+
65
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ dummy_text = <<EOT
4
+ This is a text
5
+ This is a text
6
+ This is a text
7
+ This is a text
8
+ secret
9
+ This is a text
10
+ This is a text
11
+ This is a text
12
+ EOT
13
+
14
+ class Test
15
+ include Codesake::Utils::Files
16
+ include Codesake::Engine::Core
17
+ end
18
+
19
+ shared_examples_for Codesake::Engine::Core do
20
+ before(:all) do
21
+ @mock = Test.new
22
+ File.open("test_secrets.txt", "w") do |f|
23
+ f.puts(dummy_text)
24
+ end
25
+
26
+ @mock.filename="test_secrets.txt"
27
+ @mock.read_file
28
+
29
+ end
30
+
31
+ after(:all) do
32
+ File.delete("test_secrets.txt")
33
+ end
34
+
35
+ it "provide an analyse method" do
36
+ @mock.should respond_to(:analyse)
37
+ end
38
+
39
+ context "has an analyse method returning an empty array if the input is" do
40
+ it "null" do
41
+ @mock.analyse.class.should == Array
42
+ @mock.analyse.should be_empty
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ dummy_text = <<EOT
4
+ This is a text
5
+ This is a text
6
+ This is a text
7
+ This is a text
8
+ EOT
9
+
10
+ class Test
11
+ include Codesake::Utils::Files
12
+ end
13
+
14
+ shared_examples_for Codesake::Utils::Files do
15
+ before(:all) do
16
+ @mock = Test.new
17
+ File.open("test_utils.txt", "w") do |f|
18
+ f.puts(dummy_text)
19
+ end
20
+
21
+ end
22
+ after(:all) do
23
+ File.delete("test_utils.txt")
24
+ end
25
+
26
+ ## Reading the file
27
+
28
+ it "has a read_file method" do
29
+ @mock.should respond_to(:read_file)
30
+ end
31
+
32
+ it "complains if we request to read a non existing file" do
33
+ @mock.filename = "test"
34
+ @mock.read_file.should be_false
35
+ @mock.file_content.should be_empty
36
+ end
37
+
38
+ it "read an existing file" do
39
+ @mock.filename = "test_utils.txt"
40
+ @mock.read_file.should be_true
41
+ @mock.file_content.should_not be_empty
42
+ end
43
+
44
+
45
+ it "has a loc method" do
46
+ @mock.should respond_to(:loc)
47
+ end
48
+ it "has a lines method" do
49
+ @mock.should respond_to(:lines)
50
+ end
51
+
52
+ it "has a lines_of_comment method" do
53
+ @mock.should respond_to(:lines_of_comment)
54
+ end
55
+
56
+
57
+
58
+ end
59
+
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ jsp_content =<<EOS
4
+ <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
5
+ pageEncoding="ISO-8859-1"%>
6
+ <%@page import="com.codesake.test"%>
7
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
8
+ <html>
9
+ <head>
10
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
11
+ <link rel="stylesheet" type="text/CSS" href="<%=request.getContextPath()%>/css/style.css" />
12
+ <title>Hello World</title>
13
+
14
+ <script type="text/javascript">
15
+ function confirmSubmit(name) {
16
+ return alert("test here'"+ cacheName +"'");
17
+ }
18
+
19
+ </script>
20
+
21
+ </head>
22
+ <body>
23
+
24
+ <div id="header">
25
+ <h1>Hello World</h1>
26
+
27
+ <a href="<%=request.getContextPath()%>/jsp/link1.jsp">Link 1</a>
28
+ <a href="<%=request.getContextPath()%>/jsp/link2.jsp">Link 2</a>
29
+ <a href="<%=request.getContextPath()%>/jsp/link3.jsp">Link 3</a>
30
+ <a href="<%=request.getContextPath()%>/jsp/link4.jsp">Link 4</a>
31
+ <a href="<%=request.getContextPath()%>/servlet">servlet</a>
32
+ </div>
33
+
34
+ <%
35
+ String message = (String) request.getAttribute("message");
36
+ if(message != null)
37
+ {
38
+ %>
39
+ <h4 id="message"><%=message%></h4>
40
+ <% }
41
+ else
42
+ {
43
+ %>
44
+ <h4 id="message"></h4>
45
+ <% } %>
46
+ <div id="content">
47
+ <form action="<%=request.getContextPath()%>/postHandler" method="post">
48
+ <label for="message">message:</label>
49
+ <input type="text" name="message" id="message" size="40" value="<%=request.getLocalName()%>" />
50
+ <input type="submit" value="submit" onclick="javascript: return confirmSubmit('Clienti');" />
51
+ </form>
52
+ </div>
53
+ <%
54
+ Cookie c = new Cookie("name", "a_value")
55
+ Cookie cc = new Cookie("second", 12)
56
+ %>
57
+ </body>
58
+ EOS
59
+
60
+ describe Codesake::Engine::Jsp do
61
+ before(:all) do
62
+ File.open("test.jsp", "w") do |f|
63
+ f.write(jsp_content)
64
+ end
65
+ @jsp = Codesake::Engine::Jsp.new("test.jsp", {})
66
+ @jsp.analyse
67
+ end
68
+
69
+ after(:all) do
70
+ File.delete("test.jsp") if File.exists?("test.jsp")
71
+ end
72
+
73
+ it_behaves_like Codesake::Utils::Files
74
+ # it_behaves_like Codesake::Utils::Secrets
75
+ it_behaves_like Codesake::Engine::Core
76
+
77
+ it "takes a filename as input" do
78
+ @jsp.filename.should_not be_nil
79
+ @jsp.filename.should_not be_empty
80
+ end
81
+
82
+ it "analyses a jsp for imported packages" do
83
+ expected_result = [{:package=>"com.codesake.test", :line=>3}]
84
+ @jsp.imports.should == expected_result
85
+ end
86
+
87
+ it "analyses a jsp file for attack entrypoints" do
88
+ expected_result = [{:line=>32, :param=>"message", :var=>"message"}]
89
+ @jsp.attack_entrypoints.should == expected_result
90
+ end
91
+ it "analyses a jsp file for reflected variables" do
92
+ expected_result = [{:line=>8, :var=>"request.getContextPath()", :false_positive=>true},
93
+ {:line=>24, :var=>"request.getContextPath()", :false_positive=>true},
94
+ {:line=>25, :var=>"request.getContextPath()", :false_positive=>true},
95
+ {:line=>26, :var=>"request.getContextPath()", :false_positive=>true},
96
+ {:line=>27, :var=>"request.getContextPath()", :false_positive=>true},
97
+ {:line=>28, :var=>"request.getContextPath()", :false_positive=>true},
98
+ {:line=>36, :var=>"message", :false_positive=>false},
99
+ {:line=>44, :var=>"request.getContextPath()", :false_positive=>true},
100
+ {:line=>46, :var=>"request.getLocalName()", :false_positive=>true}
101
+ ]
102
+ @jsp.reflected_xss.should == expected_result
103
+ end
104
+
105
+ it "analyses a jsp file for cookies" do
106
+ expected_result = [{:line=>51, :name=>"name", :value=>"a_value", :var=>"c"}, {:line=>52, :name=>"second", :value=>"12", :var=>"cc"}]
107
+ @jsp.cookies.should == expected_result
108
+ end
109
+
110
+
111
+
112
+
113
+
114
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Codesake::Kernel do
4
+ before(:all) do
5
+ @kernel = Codesake::Kernel.instance
6
+ end
7
+
8
+ it "has a choose_engine method" do
9
+ @kernel.should respond_to(:choose_engine)
10
+ end
11
+
12
+ it "has a detect method" do
13
+ @kernel.should respond_to(:detect)
14
+ end
15
+
16
+ it "detects a text file from its extension" do
17
+ @kernel.detect("Gemfile").should == Codesake::Kernel::TEXT
18
+ @kernel.detect("foo.txt").should == Codesake::Kernel::TEXT
19
+ end
20
+
21
+ it "detects a jsp file from its extension" do
22
+ @kernel.detect("test.jsp").should == Codesake::Kernel::JSP
23
+ end
24
+
25
+
26
+ #
27
+ # TODO: I plan to add specialized engines for those languages before
28
+ # reaching 1.0 - 20121211
29
+ #
30
+
31
+ it "detects a java file from its extension"
32
+ it "detects a c file from its extension"
33
+ it "detects a shell script from its extension"
34
+ it "detects an html file from its extension"
35
+ it "detects an haml file from its extension"
36
+ it "detects a markdown file from its extension"
37
+ it "detects a ruby file from its extension"
38
+ it "detects a php file from its extension"
39
+ it "detects a js file from its extension"
40
+ it "detects a perl file from its extension"
41
+
42
+ # Engine choosing tests
43
+
44
+ it "chooses Codesake::Engine::Text for a text file" do
45
+ @kernel.choose_engine("a_text_file", {}).class.should == Codesake::Engine::Text
46
+ end
47
+
48
+ it "chooses Codesake::Engine::Jsp for a jsp file" do
49
+ @kernel.choose_engine("test.jsp", {}).class.should == Codesake::Engine::Jsp
50
+ end
51
+
52
+ it "chooses Codesake::Engine::Java for a java file"
53
+ it "chooses Codesake::Engine::Text for a c file"
54
+ it "chooses Codesake::Engine::Text for a shell script"
55
+ it "chooses Codesake::Engine::Text for a html file"
56
+ it "chooses Codesake::Engine::Text for a haml file"
57
+ it "chooses Codesake::Engine::Text for a markdown file"
58
+ it "chooses Codesake::Engine::Text for a ruby file"
59
+ it "chooses Codesake::Engine::Text for a php file"
60
+ it "chooses Codesake::Engine::Text for a js file"
61
+ it "chooses Codesake::Engine::Text for a perl file"
62
+
63
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ dummy_text = <<EOT
5
+ This is a text
6
+ This is a text
7
+ This is a text
8
+ This is a text
9
+ secret
10
+ This is a text
11
+ This is a text
12
+ This is a text
13
+ EOT
14
+
15
+ class Test
16
+ include Codesake::Utils::Files
17
+ include Codesake::Utils::Secrets
18
+ end
19
+
20
+
21
+ shared_examples_for Codesake::Utils::Secrets do
22
+ before(:all) do
23
+ @mock = Test.new
24
+ File.open("test_secrets.txt", "w") do |f|
25
+ f.puts(dummy_text)
26
+ end
27
+
28
+ @mock.filename="test_secrets.txt"
29
+ @mock.read_file
30
+ end
31
+ after(:all) do
32
+ File.delete("test_secrets.txt")
33
+ end
34
+
35
+ context "has a list of reserved words containing" do
36
+ it "password" do
37
+ @mock.reserved?("password").should be_true
38
+ end
39
+ it "username" do
40
+ @mock.reserved?("username").should be_true
41
+ end
42
+ it "login" do
43
+ @mock.reserved?("login").should be_true
44
+ end
45
+ it "fixme" do
46
+ @mock.reserved?("fixme").should be_true
47
+ end
48
+ it "xxx" do
49
+ @mock.reserved?("xxx").should be_true
50
+ end
51
+ it "fix" do
52
+ @mock.reserved?("fix").should be_true
53
+ end
54
+ end
55
+
56
+ it "let user add a reserver word" do
57
+ @mock.reserved?("foo").should be_false
58
+ @mock.add("foo")
59
+ @mock.reserved?("foo").should be_true
60
+
61
+ end
62
+ context "has a find method" do
63
+ it "that is public" do
64
+ @mock.should respond_to(:find_reserved_keywords)
65
+ end
66
+ it "returns an empty array if 'secret' is not a reserved word in the example source" do
67
+ @mock.secrets=["noodle", "compain", "foo"]
68
+ @mock.find_reserved_keywords.should be_empty
69
+ end
70
+ it "returns true if 'secret' is a reserved word in the example source" do
71
+ @mock.secrets=["secret"]
72
+ @mock.find_reserved_keywords.should == [{:line=>5, :matcher=>"secret"}]
73
+ end
74
+
75
+
76
+ end
77
+
78
+
79
+ end
@@ -1 +1,4 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
1
4
  require 'codesake'
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ lorem_ipsum = <<EOS
4
+ Lorem ipsum dolor sit amet, secret consectetuer adipiscing elit, sed diam nonummy nibh
5
+ euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim
6
+ ad minim veniam, quis nostrud secret exerci tation ullamcorper suscipit lobortis nisl
7
+ ut aliquip ex ea commodo consequat. Duis splople autem vel eum iriure dolor in
8
+ hendrerit in vulputate velit esse secret molestie consequat, vel illum dolore eu
9
+ feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui
10
+ blandit praesent luptatum zzril password delenit augue duis dolore te feugait nulla
11
+ facilisi.
12
+
13
+ Pellentesque at dolor non lectus sagittis semper. Donec quis mi. Duis eget
14
+ pede. Phasellus arcu tellus, ultricies id, consequat id, lobortis nec, diam.
15
+ Suspendisse sed nunc. Pellentesque id magna. Morbi interdum quam at est.
16
+ Maecenas eleifend mi in urna. Praesent et lectus ac nibh luctus viverra. In vel
17
+ dolor sed nibh sollicitudin tincidunt. Ut consequat nisi sit amet nibh. Nunc mi
18
+ tortor, tristique sit amet, rhoncus porta, malesuada elementum, nisi. Integer
19
+ vitae enim quis risus aliquet gravida. Curabitur vel lorem vel erat dapibus
20
+ lobortis. Donec dignissim tellus at arcu. Quisque molestie pulvinar sem.
21
+
22
+ Nulla magna neque, ullamcorper tempus, luctus eget, malesuada ut, velit. Morbi
23
+ felis. Praesent in purus at ipsum cursus posuere. Morbi bibendum facilisis
24
+ eros. Phasellus aliquam sapien in erat. Praesent venenatis diam dignissim dui.
25
+ Praesent risus erat, iaculis ac, dapibus sed, imperdiet ac, erat. Nullam sed
26
+ ipsum. Phasellus non dolor. Donec ut elit.
27
+ EOS
28
+
29
+ describe Codesake::Engine::Text do
30
+ before(:all) do
31
+ File.open("lorem.txt", "w") do |f|
32
+ f.write(lorem_ipsum)
33
+ end
34
+ @text = Codesake::Engine::Text.new("lorem.txt")
35
+ end
36
+ after(:all) do
37
+ File.delete("lorem.txt") if File.exists?("lorem.txt")
38
+ end
39
+
40
+ it_behaves_like Codesake::Utils::Files
41
+ it_behaves_like Codesake::Utils::Secrets
42
+ it_behaves_like Codesake::Engine::Core
43
+
44
+ it "takes a filename as input" do
45
+ @text.filename.should_not be_nil
46
+ @text.filename.should_not be_empty
47
+ end
48
+
49
+ context "has a is_txt? method" do
50
+ it "and this method is public" do
51
+ Codesake::Engine::Text.should respond_to(:is_txt?)
52
+ end
53
+ it "returns false if file extension is not .txt" do
54
+ Codesake::Engine::Text.is_txt?("text.jsp").should be_false
55
+ end
56
+ it "returns true if file extension is .txt" do
57
+ Codesake::Engine::Text.is_txt?("text.txt").should be_true
58
+ end
59
+ end
60
+
61
+ it "analyse the file for reserved words" do
62
+
63
+ # secret @1, 3, 5
64
+ # password @7
65
+ expected_result = [{:line=>1, :matcher=>"secret"}, {:line=>3, :matcher=>"secret"}, {:line=>5, :matcher=>"secret"}, {:line=>7, :matcher=>"password"}]
66
+ @text.analyse.should_not be_nil
67
+ @text.reserved_keywords.size.should == 4
68
+ @text.reserved_keywords.should == expected_result
69
+
70
+ end
71
+
72
+ end