safe_yaml 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  SafeYAML
2
2
  ========
3
3
 
4
+ [![Build Status](https://travis-ci.org/dtao/safe_yaml.png)](http://travis-ci.org/dtao/safe_yaml)
5
+
4
6
  The **SafeYAML** gem provides an alternative implementation of `YAML.load` suitable for accepting user input in Ruby applications. Unlike Ruby's built-in implementation of `YAML.load`, SafeYAML's version will not expose apps to arbitrary code execution exploits (such as [the one recently discovered in Rails](http://www.reddit.com/r/netsec/comments/167c11/serious_vulnerability_in_ruby_on_rails_allowing/) (or [this one](http://www.h-online.com/open/news/item/Rails-developers-close-another-extremely-critical-flaw-1793511.html))).
5
7
 
6
8
  Installation
@@ -50,7 +52,7 @@ Observe:
50
52
  > "foo; end; puts %(I'm in yr system!); def bar": "baz"
51
53
  > EOYAML
52
54
  => "--- !ruby/hash:ExploitableClassBuilder\n\"foo; end; puts %(I'm in yr system!); def bar\": \"baz\"\n"
53
-
55
+
54
56
  > YAML.load(yaml)
55
57
  I'm in yr system!
56
58
  => #<ExploitableClassBuilder:0x007fdbbe2e25d8 @class=#<Class:0x007fdbbe2e2510>>
@@ -81,6 +83,8 @@ By default, when you require the safe_yaml gem in your project, `YAML.load` is p
81
83
 
82
84
  The default behavior can be switched to unsafe loading by calling `YAML.enable_arbitrary_object_deserialization!`. In this case, the `:safe` flag still has the same effect, but the defaults are reversed (so calling `YAML.load` will have the same behavior as if the safe_yaml gem weren't required).
83
85
 
86
+ This gem will also warn you whenever you use `YAML.load` without specifying the `:safe` option. If you do not want to see these messages in your logs, you can say `SafeYAML::OPTIONS[:suppress_warnings] = true` in an initializer.
87
+
84
88
  Notes
85
89
  -----
86
90
 
@@ -97,17 +101,21 @@ The way that SafeYAML works is by restricting the kinds of objects that can be d
97
101
 
98
102
  Additionally, deserialization of symbols can be enabled by calling `YAML.enable_symbol_parsing!`.
99
103
 
104
+ Known Issues
105
+ ------------
106
+
107
+ Also note that some Ruby libraries, particularly those requiring inter-process communication, leverage YAML's object deserialization functionality and therefore may break or otherwise be impacted by SafeYAML. The following list includes known instances of SafeYAML's interaction with other Ruby gems:
108
+
109
+ - **Guard**: Uses YAML as a serialization format for notifications. The data serialized uses symbol keys, so calling `YAML.enable_symbol_parsing!` is necessary to allow Guard to work.
110
+
111
+ The above list will grow over time, as more issues are discovered.
112
+
100
113
  Caveat
101
114
  ------
102
115
 
103
- Obviously this gem is quite young, and so the API may (read: will) change in future versions. The goal of the gem is to make it as easy as possible to protect existing applications from object deserialization exploits. Any and all feedback is more than welcome.
116
+ This gem is quite young, and so the API may (read: *will*) change in future versions. The goal of the gem is to make it as easy as possible to protect existing applications from object deserialization exploits. Any and all feedback is more than welcome.
104
117
 
105
118
  Requirements
106
119
  ------------
107
120
 
108
121
  SafeYAML requires Ruby 1.8.7 or newer and works with both [Syck](http://www.ruby-doc.org/stdlib-1.8.7/libdoc/yaml/rdoc/YAML.html) and [Psych](http://github.com/tenderlove/psych).
109
-
110
- Code Status
111
- -------------
112
-
113
- [![Build Status](https://secure.travis-ci.org/dtao/safe_yaml.png)](http://travis-ci.org/dtao/safe_yaml)
data/lib/safe_yaml.rb CHANGED
@@ -12,7 +12,8 @@ require "safe_yaml/version"
12
12
  module SafeYAML
13
13
  OPTIONS = {
14
14
  :enable_symbol_parsing => false,
15
- :enable_arbitrary_object_deserialization => false
15
+ :enable_arbitrary_object_deserialization => false,
16
+ :suppress_warnings => false
16
17
  }
17
18
  end
18
19
 
@@ -131,7 +132,7 @@ module YAML
131
132
 
132
133
  if safe_mode.nil?
133
134
  mode = SafeYAML::OPTIONS[:enable_arbitrary_object_deserialization] ? "unsafe" : "safe"
134
- Kernel.warn "Called '#{method}' without the :safe option -- defaulting to #{mode} mode."
135
+ Kernel.warn "Called '#{method}' without the :safe option -- defaulting to #{mode} mode." unless SafeYAML::OPTIONS[:suppress_warnings]
135
136
  safe_mode = !SafeYAML::OPTIONS[:enable_arbitrary_object_deserialization]
136
137
  end
137
138
 
@@ -3,15 +3,15 @@ module SafeYAML
3
3
  QUOTE_STYLES = [:quote1, :quote2]
4
4
 
5
5
  def resolve_node(node)
6
- case node.kind
7
- when :map
6
+ case node.value
7
+ when Hash
8
8
  return resolve_map(node)
9
- when :seq
9
+ when Array
10
10
  return resolve_seq(node)
11
- when :scalar
11
+ when String
12
12
  return resolve_scalar(node)
13
13
  else
14
- raise "Don't know how to resolve a '#{node.kind}' node!"
14
+ raise "Don't know how to resolve this node: #{node.inspect}"
15
15
  end
16
16
  end
17
17
 
@@ -1,3 +1,3 @@
1
1
  module SafeYAML
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
@@ -150,6 +150,17 @@ describe YAML do
150
150
  end
151
151
  }
152
152
 
153
+ context "with :suppress_warnings set to true" do
154
+ before :each do SafeYAML::OPTIONS[:suppress_warnings] = true; end
155
+ after :each do SafeYAML::OPTIONS[:suppress_warnings] = false; end
156
+
157
+ it "doesn't issue a warning if :suppress_warnings option is set to true" do
158
+ SafeYAML::OPTIONS[:suppress_warnings] = true
159
+ Kernel.should_not_receive(:warn)
160
+ YAML.load(*arguments)
161
+ end
162
+ end
163
+
153
164
  it "issues a warning if the :safe option is omitted" do
154
165
  silence_warnings do
155
166
  Kernel.should_receive(:warn)
data/spec/shared_specs.rb CHANGED
@@ -75,6 +75,37 @@ module SharedSpecs
75
75
  result.should == { "foo" => "" }
76
76
  end
77
77
 
78
+ it "correctly reverse-translates strings encoded via #to_yaml" do
79
+ parse "5.10".to_yaml
80
+ result.should == "5.10"
81
+ end
82
+
83
+ it "does not specially parse any double-quoted strings" do
84
+ parse <<-YAML
85
+ - "1"
86
+ - "3.14"
87
+ - "true"
88
+ - "false"
89
+ - "2013-02-03"
90
+ - "2013-02-03 16:27:00 -0600"
91
+ YAML
92
+
93
+ result.should == ["1", "3.14", "true", "false", "2013-02-03", "2013-02-03 16:27:00 -0600"]
94
+ end
95
+
96
+ it "does not specially parse any single-quoted strings" do
97
+ parse <<-YAML
98
+ - '1'
99
+ - '3.14'
100
+ - 'true'
101
+ - 'false'
102
+ - '2013-02-03'
103
+ - '2013-02-03 16:27:00 -0600'
104
+ YAML
105
+
106
+ result.should == ["1", "3.14", "true", "false", "2013-02-03", "2013-02-03 16:27:00 -0600"]
107
+ end
108
+
78
109
  it "deals just fine with nested maps" do
79
110
  parse <<-YAML
80
111
  foo:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_yaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-02 00:00:00.000000000 Z
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Parse YAML safely, without that pesky arbitrary object deserialization
15
15
  vulnerability