owasp-esapi-ruby 0.30.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 (56) hide show
  1. data/.document +5 -0
  2. data/AUTHORS +5 -0
  3. data/ChangeLog +69 -0
  4. data/ISSUES +0 -0
  5. data/LICENSE +24 -0
  6. data/README +51 -0
  7. data/Rakefile +63 -0
  8. data/VERSION +1 -0
  9. data/lib/codec/base_codec.rb +99 -0
  10. data/lib/codec/css_codec.rb +101 -0
  11. data/lib/codec/encoder.rb +330 -0
  12. data/lib/codec/html_codec.rb +424 -0
  13. data/lib/codec/javascript_codec.rb +119 -0
  14. data/lib/codec/mysql_codec.rb +131 -0
  15. data/lib/codec/oracle_codec.rb +46 -0
  16. data/lib/codec/os_codec.rb +78 -0
  17. data/lib/codec/percent_codec.rb +53 -0
  18. data/lib/codec/pushable_string.rb +114 -0
  19. data/lib/codec/vbscript_codec.rb +64 -0
  20. data/lib/codec/xml_codec.rb +173 -0
  21. data/lib/esapi.rb +68 -0
  22. data/lib/exceptions.rb +37 -0
  23. data/lib/executor.rb +20 -0
  24. data/lib/owasp-esapi-ruby.rb +13 -0
  25. data/lib/sanitizer/xss.rb +59 -0
  26. data/lib/validator/base_rule.rb +90 -0
  27. data/lib/validator/date_rule.rb +92 -0
  28. data/lib/validator/email.rb +29 -0
  29. data/lib/validator/float_rule.rb +76 -0
  30. data/lib/validator/generic_validator.rb +26 -0
  31. data/lib/validator/integer_rule.rb +61 -0
  32. data/lib/validator/string_rule.rb +146 -0
  33. data/lib/validator/validator_error_list.rb +48 -0
  34. data/lib/validator/zipcode.rb +27 -0
  35. data/spec/codec/css_codec_spec.rb +61 -0
  36. data/spec/codec/html_codec_spec.rb +87 -0
  37. data/spec/codec/javascript_codec_spec.rb +45 -0
  38. data/spec/codec/mysql_codec_spec.rb +44 -0
  39. data/spec/codec/oracle_codec_spec.rb +23 -0
  40. data/spec/codec/os_codec_spec.rb +51 -0
  41. data/spec/codec/percent_codec_spec.rb +34 -0
  42. data/spec/codec/vbcript_codec_spec.rb +23 -0
  43. data/spec/codec/xml_codec_spec.rb +83 -0
  44. data/spec/owasp_esapi_encoder_spec.rb +226 -0
  45. data/spec/owasp_esapi_executor_spec.rb +9 -0
  46. data/spec/owasp_esapi_ruby_email_validator_spec.rb +39 -0
  47. data/spec/owasp_esapi_ruby_xss_sanitizer_spec.rb +66 -0
  48. data/spec/owasp_esapi_ruby_zipcode_validator_spec.rb +42 -0
  49. data/spec/spec_helper.rb +10 -0
  50. data/spec/validator/base_rule_spec.rb +29 -0
  51. data/spec/validator/date_rule_spec.rb +40 -0
  52. data/spec/validator/float_rule_spec.rb +31 -0
  53. data/spec/validator/integer_rule_spec.rb +51 -0
  54. data/spec/validator/string_rule_spec.rb +103 -0
  55. data/spec/validator_skeleton.rb +150 -0
  56. metadata +235 -0
@@ -0,0 +1,27 @@
1
+ require 'validator/generic_validator'
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Validator
6
+
7
+ # This is a validator class for zip codes.
8
+ class Zipcode < GenericValidator
9
+
10
+ ITALIAN_ZIPCODE = "^\\d{5}$"
11
+ US_ZIPCODE = "^\\d{5}(\\-\\d{4})?$"
12
+
13
+ # Creates a new Zipcode validator.
14
+ # @param custom_regex if you don't find your locale zip code regular expression, you can provide a
15
+ # very custom one
16
+ def initialize(options = nil)
17
+ # Matcher is tuned to match a valid US ZIP CODE, that means either 5 numbers, or 5 numbers,
18
+ # plus a dash, then 4 more numbers.
19
+ @matcher = US_ZIPCODE
20
+ @matcher = options["custom_regex"] unless (options.nil? || ! options.has_key?("custom_regex"))
21
+ super(@matcher)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe CssCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::CssCodec.new }
8
+
9
+ it "should encode my '<' as \\3c" do
10
+ m = codec.encode([],"<")
11
+ m.should == '\\3c '
12
+ end
13
+
14
+ it "should decode \\abcdefg and replace the invliad code point" do
15
+ s = "\\abcdefg"
16
+ codec.decode(s).should == "\uFFFDg"
17
+ end
18
+ it "should encode 0x100 as \\100" do
19
+ s = 0x100.chr(Encoding::UTF_8)
20
+ m = codec.encode([],s[0])
21
+ m.should == "\\100 "
22
+ end
23
+
24
+ it "should decode '\\<' to '<'" do
25
+ m = codec.decode("\\<")
26
+ m.should == "<"
27
+ end
28
+
29
+ it "should decode '\\41xyz' to Axyz" do
30
+ m = codec.decode("\\41xyz")
31
+ m.should == "Axyz"
32
+ end
33
+
34
+ it "should decode '\\000041abc' to 'Aabc'" do
35
+ m = codec.decode("\\000041abc")
36
+ m.should == "Aabc"
37
+ end
38
+
39
+ it "should decode '\\41 abc' to 'Aabc'" do
40
+ m = codec.decode("\\41 abc")
41
+ m.should == "Aabc"
42
+ end
43
+
44
+ it "should decode 'abc\\\nxyz' to 'abcxyz'" do
45
+ m = codec.decode("abc\\\nxyz")
46
+ m.should == "abcxyz"
47
+ end
48
+
49
+ it "should decode 'abc\\\r\nxyz' to 'abcxyz'" do
50
+ m = codec.decode("abc\\\r\nxyz")
51
+ m.should == "abcxyz"
52
+ end
53
+
54
+ it "should decode \\3c as <" do
55
+ codec.decode("\\3c").should == "<"
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,87 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe HtmlCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::HtmlCodec.new }
8
+
9
+ it "should not change test" do
10
+ codec.encode([],"test").should == "test"
11
+ end
12
+
13
+ it "should encode < as &lt;" do
14
+ codec.encode([],"<").should == "&lt;"
15
+ end
16
+
17
+ it "should encode 0x100 as &#x100;" do
18
+ s = 0x100.chr(Encoding::UTF_8)
19
+ m = codec.encode([],s[0])
20
+ m.should == "&#x100;"
21
+ end
22
+
23
+ it "should decode &#x74;&#x65;&#x73;&#x74;! as test!" do
24
+ codec.decode("&#x74;&#x65;&#x73;&#x74;!").should == "test!"
25
+ end
26
+
27
+ it "should skip &jeff; an invlaid attribute" do
28
+ codec.decode("&jeff;").should == "&jeff;"
29
+ end
30
+
31
+ # dynamic tests for various inputs to decode
32
+ {
33
+ "&amp;" => "&",
34
+ "&amp;X" => "&X",
35
+ "&amp" => "&",
36
+ "&ampX" => "&X",
37
+ "&lt;" => "<",
38
+ "&lt;X" => "<X",
39
+ "&lt" => "<",
40
+ "&ltX"=> "<X",
41
+ "&#60" => "<",
42
+ "&sup2;" => "\u00B2",
43
+ "&sup2;X" => "\u00B2X",
44
+ "&sup2" => "\u00B2",
45
+ "&sup2X" => "\u00B2X",
46
+ "&sup3;" => "\u00B3",
47
+ "&sup3;X" => "\u00B3X",
48
+ "&sup3" => "\u00B3",
49
+ "&sup3X" => "\u00B3X",
50
+ "&sup1;" => "\u00B9",
51
+ "&sup1;X" => "\u00B9X",
52
+ "&sup1" => "\u00B9",
53
+ "&sup1X" => "\u00B9X",
54
+ "&sup;" => "\u2283",
55
+ "&sup;X" => "\u2283X",
56
+ "&sup" => "\u2283",
57
+ "&supX" => "\u2283X",
58
+ "&supe;" => "\u2287",
59
+ "&supe;X" => "\u2287X",
60
+ "&supe" => "\u2287",
61
+ "&supeX" => "\u2287X",
62
+ "&pi;" => "\u03C0",
63
+ "&pi;X" => "\u03C0X",
64
+ "&pi" => "\u03C0",
65
+ "&piX" => "\u03C0X",
66
+ "&piv;" => "\u03D6",
67
+ "&piv;X" => "\u03D6X",
68
+ "&piv" => "\u03D6",
69
+ "&pivX" => "\u03D6X",
70
+ "&theta;" => "\u03B8",
71
+ "&theta;X" => "\u03B8X",
72
+ "&theta" => "\u03B8",
73
+ "&thetaX" => "\u03B8X",
74
+ "&thetasym;" => "\u03D1",
75
+ "&thetasym;X" => "\u03D1X",
76
+ "&thetasym" => "\u03D1",
77
+ "&thetasymX" => "\u03D1X",
78
+ }.each_pair do |k,v|
79
+ it "should decode #{k} as #{v}" do
80
+ codec.decode(k).should == v
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe JavascriptCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::JavascriptCodec.new }
8
+
9
+ it "should decode \\x3c as <" do
10
+ codec.decode("\\x3c").should == "<"
11
+ end
12
+
13
+ it "should encode < as \\x3C" do
14
+ codec.encode([],"<").should == "\\x3C"
15
+ end
16
+
17
+ it "should encode 0x100 as \\u0100" do
18
+ s = 0x100.chr(Encoding::UTF_8)
19
+ codec.encode([],s[0]).should == "\\u0100"
20
+ end
21
+
22
+ it "should encode <script> as \\x3Cscript\\x3E" do
23
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_JAVASCRIPT,"<script>").should == "\\x3Cscript\\x3E"
24
+ end
25
+
26
+ it "should encoder !@$%()=+{}[] as \\x21\\x40\\x24\\x25\\x28\\x29\\x3D\\x2B\\x7B\\x7D\\x5B\\x5D" do
27
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_JAVASCRIPT,"!@$%()=+{}[]").should == "\\x21\\x40\\x24\\x25\\x28\\x29\\x3D\\x2B\\x7B\\x7D\\x5B\\x5D"
28
+ end
29
+
30
+ it "shoudl encode ',.-_ ' as ',.\\x2D_\\x20'" do
31
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_JAVASCRIPT,",.-_ ").should == ",.\\x2D_\\x20"
32
+ end
33
+
34
+ it "should decode \\f as \f" do
35
+ codec.decode("\\f").should == "\f"
36
+ end
37
+
38
+ it "should decode \\b as \b" do
39
+ codec.decode("\\b").should == "\b"
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe MySQLCodec do
7
+ let (:ansi_codec) { Owasp::Esapi::Codec::MySQLCodec.new(Owasp::Esapi::Codec::MySQLCodec::ANSI_MODE) }
8
+ let (:mysql_codec) { Owasp::Esapi::Codec::MySQLCodec.new(Owasp::Esapi::Codec::MySQLCodec::MYSQL_MODE) }
9
+ let (:big_char) { }
10
+
11
+ it "should encode \' as \'\' in ANSI mode" do
12
+ ansi_codec.encode([],"\'").should == "\'\'"
13
+ end
14
+
15
+ it "should encode < as \\< in MYSQL mode" do
16
+ mysql_codec.encode([],"<").should == "\\<"
17
+ end
18
+
19
+ it "should encode 0x100 as \\0x100 in MYSQL mode" do
20
+ s = 0x100.chr(Encoding::UTF_8)[0]
21
+ mysql_codec.encode([],s) == "\\#{s}"
22
+ end
23
+
24
+ it "should encode 0x100 as 0x100 in ANSI mode" do
25
+ s = 0x100.chr(Encoding::UTF_8)[0]
26
+ ansi_codec.encode([],s) == "#{s}"
27
+ end
28
+
29
+ it "should decode '' as ' in ANSI mode" do
30
+ ansi_codec.decode("\'\'").should == "\'"
31
+ end
32
+
33
+ it "should decode \\< as < in MYSQL mode" do
34
+ mysql_codec.decode("\\<").should == "<"
35
+ end
36
+
37
+ it "should fail to create a code with an invalid mode" do
38
+ lambda { Owasp::Esapi::Codec::MySQLCodec.new(5)}.should raise_error(RangeError)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe OracleCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::OracleCodec.new }
8
+
9
+ it "should encode eddie's stuff as eddie''s stuff" do
10
+ codec.encode([],"eddie's stuff").should == "eddie''s stuff"
11
+ end
12
+ it "should encode \' as \'\'" do
13
+ codec.encode([],"\'").should == "\'\'"
14
+ end
15
+
16
+ it "should decode \'\' as \'" do
17
+ codec.decode("\'\'").should == "\'"
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe OsCodec do
7
+ let(:unix_codec) {Owasp::Esapi::Codec::OsCodec.new( Owasp::Esapi::Codec::OsCodec::UNIX_HOST)}
8
+ let(:win_codec) {Owasp::Esapi::Codec::OsCodec.new( Owasp::Esapi::Codec::OsCodec::WINDOWS_HOST)}
9
+
10
+ it "should detect the actual host os" do
11
+ codec = Owasp::Esapi::Codec::OsCodec.new
12
+ codec.os.should == Owasp::Esapi::Codec::OsCodec::UNIX_HOST
13
+ end
14
+
15
+ it "should decode ^< as < for windows" do
16
+ win_codec.decode("^<").should == "<"
17
+ end
18
+
19
+ it "should decode \\< as < for unix" do
20
+ unix_codec.decode("\\<").should == "<"
21
+ end
22
+
23
+ it "should encode c:\\jeff with ^ chars for windows" do
24
+ win_codec.encode([],"C:\\jeff").should == "C^:^\\jeff"
25
+ end
26
+
27
+ it "should encode dir & foo with ^ chars for windows" do
28
+ win_codec.encode([],"dir & foo").should == "dir^ ^&^ foo"
29
+
30
+ end
31
+
32
+ it "should encode c:\\jeff with \\ chars for unix" do
33
+ unix_codec.encode(Owasp::Esapi::Encoder::CHAR_ALPHANUMERIC,"C:\\jeff").should == "C\\:\\\\jeff"
34
+ end
35
+
36
+ it "should encode dir & foo with \\ chars for unix" do
37
+ unix_codec.encode([],"dir & foo").should == "dir\\ \\&\\ foo"
38
+ end
39
+
40
+ it "should encode /etc/hosts with \\ chars for unix" do
41
+ unix_codec.encode(['-'],"/etc/hosts").should == "\\/etc\\/hosts"
42
+ end
43
+
44
+ it "should encode /etc/hosts; ls -l with \\ chars for unix" do
45
+ unix_codec.encode(['-'],"/etc/hosts; ls -l").should == "\\/etc\\/hosts\\;\\ ls\\ -l"
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ # percent encode aka URL encoding
4
+ module Owasp
5
+ module Esapi
6
+ module Codec
7
+ describe PercentCodec do
8
+ let (:codec) { Owasp::Esapi::Codec::PercentCodec.new }
9
+
10
+ it "should decode %3c as <" do
11
+ codec.decode("%3c").should == "<"
12
+ end
13
+
14
+ it "should encode < as %3C" do
15
+ codec.encode([],"<").should == "%3C"
16
+ end
17
+
18
+ it "should encode 0x100 as %C4%80" do
19
+ s = 0x100.chr(Encoding::UTF_8)
20
+ codec.encode([],s[0]).should == "%C4%80"
21
+ end
22
+
23
+ it "should decode %25F as %F" do
24
+ codec.decode("%25F").should == "%F"
25
+ end
26
+
27
+ it "should encode 'Stop!' said Fred as %27Stop%21%27+said+Fred" do
28
+ codec.encode([],"'Stop!' said Fred").should == "%27Stop%21%27+said+Fred"
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe VbScriptCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::VbScriptCodec.new }
8
+ it "should encode < as chrw(60)" do
9
+ codec.encode([],"<").should == "chrw(60)"
10
+ end
11
+ it "should encode 0x100 as \\u0100" do
12
+ s = 0x100.chr(Encoding::UTF_8)
13
+ codec.encode([],s[0]).should == "chrw(256)"
14
+ end
15
+
16
+ it "should decode '\"<' as <" do
17
+ codec.decode("\"<").should == "<"
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../spec_helper')
2
+
3
+ module Owasp
4
+ module Esapi
5
+ module Codec
6
+ describe XmlCodec do
7
+ let (:codec) { Owasp::Esapi::Codec::XmlCodec.new }
8
+ describe 'XML encoding' do
9
+ it "should encode nil as nil" do
10
+ codec.encode([],nil).should == nil
11
+ end
12
+
13
+ it "should encode ' ' as ' '" do
14
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XML," ").should == " "
15
+ end
16
+
17
+ it "should encode <script> as &#x3c;script&#x3e;" do
18
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XML,"<script>").should == "&#x3c;script&#x3e;"
19
+ end
20
+
21
+ it "should encode ,.-_ as same" do
22
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XML,",.-_").should == ",.-_"
23
+ end
24
+
25
+ it "should encode !@$%()=+{}[] as &#x21;&#x40;&#x24;&#x25;&#x28;&#x29;&#x3d;&#x2b;&#x7b;&#x7d;&#x5b;&#x5d;" do
26
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XML,"!@$%()=+{}[]").should == "&#x21;&#x40;&#x24;&#x25;&#x28;&#x29;&#x3d;&#x2b;&#x7b;&#x7d;&#x5b;&#x5d;"
27
+ end
28
+
29
+ it "should encode \u00A3 as &#xa3;" do
30
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XML,"\u00A3").should == "&#xa3;"
31
+ end
32
+ end
33
+
34
+ describe 'Attributes Encoding' do
35
+ it "should encode ' ' as ' '" do
36
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XMLATTR," ").should == " "
37
+ end
38
+
39
+ it "should encode <script> as &#x3c;script&#x3e;" do
40
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XMLATTR,"<script>").should == "&#x3c;script&#x3e;"
41
+ end
42
+
43
+ it "should encode ,.-_ as same" do
44
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XMLATTR,",.-_").should == ",.-_"
45
+ end
46
+
47
+ it "should encode !@$%()=+{}[] as &#x21;&#x40;&#x24;&#x25;&#x28;&#x29;&#x3d;&#x2b;&#x7b;&#x7d;&#x5b;&#x5d;" do
48
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XMLATTR,"!@$%()=+{}[]").should == "&#x21;&#x40;&#x24;&#x25;&#x28;&#x29;&#x3d;&#x2b;&#x7b;&#x7d;&#x5b;&#x5d;"
49
+ end
50
+
51
+ it "should encode \u00A3 as &#xa3;" do
52
+ codec.encode(Owasp::Esapi::Encoder::IMMUNE_XMLATTR,"\u00A3").should == "&#xa3;"
53
+ end
54
+ end
55
+
56
+ describe 'Decoding' do
57
+ {
58
+ "AB_YZ" => "AB_YZ",
59
+ "AB&gt;YZ" => "AB>YZ",
60
+ "AB&amp;YZ" => "AB&YZ",
61
+ "AB&quot;YZ" => "AB\"YZ",
62
+ "AB&apos;YZ" => "AB'YZ",
63
+ "AB&quot;" => "AB\"",
64
+ "&quot;YZ" => "\"YZ",
65
+ "&quot;" => "\"",
66
+ "AB&quot" => "AB&quot",
67
+ "&quotYZ" => "&quotYZ",
68
+ "&quot" => "&quot",
69
+ "AB&pound;" => "AB&pound;",
70
+ "&pound;YZ" => "&pound;YZ",
71
+ "&pound;" => "&pound;",
72
+ "AB&#64;YZ" => "AB@YZ",
73
+ "AB&#x40;YZ" => "AB@YZ"
74
+ }.each_pair do |k,v|
75
+ it "should decode #{k} as #{v}" do
76
+ codec.decode(k).should == v
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end