safe_yaml 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6cf9f3e405ec65c54f30eaec331423a67877dc34
4
- data.tar.gz: 0cf7116a88485be0057ff010ab330569391a9e2e
3
+ metadata.gz: fac2ccd0e0ff144a5b72c1597d16206e9c401753
4
+ data.tar.gz: c13a8b54286042faf6c3c2caa9fd2ec6d436fe1e
5
5
  SHA512:
6
- metadata.gz: 63cb08bcc97ac6e4bf25e1da93f047f0edf1726ea404864e7e47fc920dd3c8f8df988b7e532efbb31ef6d611c24cf43577978eee12817e273e8ea254b2f55203
7
- data.tar.gz: 89be3d3d4be1c8f9dc54f7d41842a443b6d8fe71586c7d79a3002fc87a71db83809d59679f431221877fdd2fc8da3a0e88ed7b79a534b1d0cc75d2218c12f4c6
6
+ metadata.gz: f5bedc29148ac5d69c163793ef490ad22261c63ca7b390e80f4a405d62a7ccef5d91520344b6901ca785db584bbf197b0ec4a2c55170fa6b6adce6b077151f41
7
+ data.tar.gz: 77a93e398b12f8661b8fc9ab672b4d5278e5c4e2e6a7c615ee162934ad5b0c23867a94e3d2425f543563e5e04890fc76f96e7e25c99ccc8c94740c1e948212ae
data/README.md CHANGED
@@ -172,6 +172,7 @@ Also be aware that some Ruby libraries, particularly those requiring inter-proce
172
172
  1. set the `:deserialize_symbols` option to `true`,
173
173
  2. whitelist some of the types in your serialized data via `SafeYAML.whitelist!` or the `:whitelisted_tags` option, or
174
174
  3. both
175
+ - [**delayed_job**](https://github.com/collectiveidea/delayed_job): Uses YAML to serialize the objects on which delayed methods are invoked (with `delay`). The safest solution in this case is to use `SafeYAML.whitelist!` to whitelist the types you need to serialize.
175
176
  - [**Guard**](https://github.com/guard/guard): Uses YAML as a serialization format for notifications. The data serialized uses symbolic keys, so setting `SafeYAML::OPTIONS[:deserialize_symbols] = true` is necessary to allow Guard to work.
176
177
  - [**sidekiq**](https://github.com/mperham/sidekiq): Uses a YAML configiuration file with symbolic keys, so setting `SafeYAML::OPTIONS[:deserialize_symbols] = true` should allow it to work.
177
178
 
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
+
5
+ require 'optparse'
6
+ require 'safe_yaml/load'
7
+
8
+ options = {}
9
+ option_parser = OptionParser.new do |opts|
10
+ opts.banner = "Usage: safe_yaml [options]"
11
+
12
+ opts.on("-f", "--file=<path>", "Parse the given YAML file, dump the result to STDOUT") do |file|
13
+ options[:file] = file
14
+ end
15
+
16
+ opts.on("--libyaml-check", "Check for libyaml vulnerability CVE-2014-2525 on your system") do
17
+ options[:libyaml_check] = true
18
+ end
19
+ end
20
+
21
+ option_parser.parse!
22
+
23
+ def report_libyaml_ok
24
+ puts "\e[32mGood news! You definitely have either a patched or up-to-date libyaml version :)\e[39m"
25
+ end
26
+
27
+ def check_for_overflow_bug
28
+ YAML.load("--- !#{'%20' * 100}")
29
+ report_libyaml_ok
30
+ end
31
+
32
+ def perform_libyaml_check(force=false)
33
+ unless SafeYAML::LibyamlChecker.libyaml_version_ok?
34
+ warn <<-EOM.gsub(/^ +/, ' ')
35
+
36
+ \e[33mSafeYAML Warning\e[39m
37
+ \e[33m----------------\e[39m
38
+
39
+ \e[31mYou may have an outdated version of libyaml (#{SafeYAML::LibyamlChecker::LIBYAML_VERSION}) installed on your system.\e[39m
40
+
41
+ Prior to 0.1.6, libyaml is vulnerable to a heap overflow exploit from malicious YAML payloads.
42
+
43
+ For more info, see:
44
+ https://www.ruby-lang.org/en/news/2014/03/29/heap-overflow-in-yaml-uri-escape-parsing-cve-2014-2525/
45
+ EOM
46
+ end
47
+
48
+ puts <<-EOM.gsub(/^ +/, ' ')
49
+
50
+ Hit Enter to check if your version of libyaml is vulnerable. This will run a test \e[31mwhich may crash\e[39m
51
+ \e[31mthe current process\e[39m. If it does, your system is vulnerable and you should do something about it.
52
+
53
+ Type "nm" and hit Enter if you don't want to run the check.
54
+
55
+ See the project wiki for more info:
56
+
57
+ https://github.com/dtao/safe_yaml/wiki/The-libyaml-vulnerability
58
+ EOM
59
+
60
+ if STDIN.readline.chomp("\n") != 'nm'
61
+ check_for_overflow_bug
62
+ end
63
+ end
64
+
65
+ if options[:libyaml_check]
66
+ perform_libyaml_check(options[:force_libyaml_check])
67
+
68
+ elsif options[:file]
69
+ yaml = File.read(options[:file])
70
+ result = SafeYAML.load(yaml)
71
+ puts result.inspect
72
+
73
+ else
74
+ puts option_parser.help
75
+ end
@@ -0,0 +1,36 @@
1
+ require "set"
2
+
3
+ module SafeYAML
4
+ class LibyamlChecker
5
+ LIBYAML_VERSION = Psych::LIBYAML_VERSION rescue nil
6
+
7
+ # Do proper version comparison (e.g. so 0.1.10 is >= 0.1.6)
8
+ SAFE_LIBYAML_VERSION = Gem::Version.new("0.1.6")
9
+
10
+ KNOWN_PATCHED_LIBYAML_VERSIONS = Set.new([
11
+ # http://people.canonical.com/~ubuntu-security/cve/2014/CVE-2014-2525.html
12
+ "0.1.4-2ubuntu0.12.04.3",
13
+ "0.1.4-2ubuntu0.12.10.3",
14
+ "0.1.4-2ubuntu0.13.10.3",
15
+ "0.1.4-3ubuntu3",
16
+
17
+ # https://security-tracker.debian.org/tracker/CVE-2014-2525
18
+ "0.1.3-1+deb6u4",
19
+ "0.1.4-2+deb7u4",
20
+ "0.1.4-3.2"
21
+ ]).freeze
22
+
23
+ def self.libyaml_version_ok?
24
+ return true if YAML_ENGINE != "psych" || defined?(JRUBY_VERSION)
25
+ return true if Gem::Version.new(LIBYAML_VERSION || "0") >= SAFE_LIBYAML_VERSION
26
+ return libyaml_patched?
27
+ end
28
+
29
+ def self.libyaml_patched?
30
+ return false if (`which dpkg` rescue '').empty?
31
+ libyaml_version = `dpkg -s libyaml-0-2`.match(/^Version: (.*)$/)
32
+ return false if libyaml_version.nil?
33
+ KNOWN_PATCHED_LIBYAML_VERSIONS.include?(libyaml_version[1])
34
+ end
35
+ end
36
+ end
@@ -1,38 +1,13 @@
1
+ require "set"
1
2
  require "yaml"
2
3
 
3
4
  # This needs to be defined up front in case any internal classes need to base
4
5
  # their behavior off of this.
5
6
  module SafeYAML
6
7
  YAML_ENGINE = defined?(YAML::ENGINE) ? YAML::ENGINE.yamler : "syck"
7
- LIBYAML_VERSION = YAML_ENGINE == "psych" && Psych.const_defined?("LIBYAML_VERSION", false) ? Psych::LIBYAML_VERSION : nil
8
-
9
- def self.check_libyaml_version
10
- if YAML_ENGINE == "psych" && (LIBYAML_VERSION.nil? || LIBYAML_VERSION < "0.1.6")
11
- Kernel.warn <<-EOWARNING.gsub(/^ +/, ' ')
12
-
13
- \e[33mSafeYAML Warning\e[39m
14
- \e[33m----------------\e[39m
15
-
16
- \e[31mYou appear to have an outdated version of libyaml (#{LIBYAML_VERSION}) installed on your system.\e[39m
17
-
18
- Prior to 0.1.6, libyaml is vulnerable to a heap overflow exploit from malicious YAML payloads.
19
-
20
- For more info, see:
21
- https://www.ruby-lang.org/en/news/2014/03/29/heap-overflow-in-yaml-uri-escape-parsing-cve-2014-2525/
22
-
23
- The easiest thing to do right now is probably to update Psych to the latest version and enable
24
- the 'bundled-libyaml' option, which will install a vendored libyaml with the vulnerability patched:
25
-
26
- \e[32mgem install psych -- --enable-bundled-libyaml\e[39m
27
-
28
- EOWARNING
29
- end
30
- end
31
8
  end
32
9
 
33
- SafeYAML.check_libyaml_version
34
-
35
- require "set"
10
+ require "safe_yaml/libyaml_checker"
36
11
  require "safe_yaml/deep"
37
12
  require "safe_yaml/parse/hexadecimal"
38
13
  require "safe_yaml/parse/sexagesimal"
@@ -1,3 +1,3 @@
1
1
  module SafeYAML
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -13,6 +13,7 @@ Gem::Specification.new do |gem|
13
13
  gem.files = `git ls-files`.split($\)
14
14
  gem.test_files = gem.files.grep(%r{^spec/})
15
15
  gem.require_paths = ["lib"]
16
+ gem.executables = ["safe_yaml"]
16
17
 
17
18
  gem.required_ruby_version = ">= 1.8.7"
18
19
  end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe SafeYAML::LibyamlChecker do
4
+ describe "check_libyaml_version" do
5
+ REAL_YAML_ENGINE = SafeYAML::YAML_ENGINE
6
+ REAL_LIBYAML_VERSION = SafeYAML::LibyamlChecker::LIBYAML_VERSION
7
+
8
+ let(:libyaml_patched) { false }
9
+
10
+ before :each do
11
+ SafeYAML::LibyamlChecker.stub(:libyaml_patched?).and_return(libyaml_patched)
12
+ end
13
+
14
+ after :each do
15
+ silence_warnings do
16
+ SafeYAML::YAML_ENGINE = REAL_YAML_ENGINE
17
+ SafeYAML::LibyamlChecker::LIBYAML_VERSION = REAL_LIBYAML_VERSION
18
+ end
19
+ end
20
+
21
+ def test_libyaml_version_ok(expected_result, yaml_engine, libyaml_version=nil)
22
+ silence_warnings do
23
+ SafeYAML.const_set("YAML_ENGINE", yaml_engine)
24
+ SafeYAML::LibyamlChecker.const_set("LIBYAML_VERSION", libyaml_version)
25
+ SafeYAML::LibyamlChecker.libyaml_version_ok?.should == expected_result
26
+ end
27
+ end
28
+
29
+ unless defined?(JRUBY_VERSION)
30
+ it "issues no warnings when 'Syck' is the YAML engine" do
31
+ test_libyaml_version_ok(true, "syck")
32
+ end
33
+
34
+ it "issues a warning if Psych::LIBYAML_VERSION is not defined" do
35
+ test_libyaml_version_ok(false, "psych")
36
+ end
37
+
38
+ it "issues a warning if Psych::LIBYAML_VERSION is < 0.1.6" do
39
+ test_libyaml_version_ok(false, "psych", "0.1.5")
40
+ end
41
+
42
+ it "issues no warning if Psych::LIBYAML_VERSION is == 0.1.6" do
43
+ test_libyaml_version_ok(true, "psych", "0.1.6")
44
+ end
45
+
46
+ it "issues no warning if Psych::LIBYAML_VERSION is > 0.1.6" do
47
+ test_libyaml_version_ok(true, "psych", "1.0.0")
48
+ end
49
+
50
+ it "does a proper version comparison (not just a string comparison)" do
51
+ test_libyaml_version_ok(true, "psych", "0.1.10")
52
+ end
53
+
54
+ context "when the system has a known patched libyaml version" do
55
+ let(:libyaml_patched) { true }
56
+
57
+ it "issues no warning, even when Psych::LIBYAML_VERSION < 0.1.6" do
58
+ test_libyaml_version_ok(true, "psych", "0.1.4")
59
+ end
60
+ end
61
+ end
62
+
63
+ if defined?(JRUBY_VERSION)
64
+ it "issues no warning, as JRuby doesn't use libyaml" do
65
+ test_libyaml_version_ok(true, "psych", "0.1.4")
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,14 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe YAML do
4
- # Essentially stolen from:
5
- # https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10-25
6
- def silence_warnings
7
- $VERBOSE = nil; yield
8
- ensure
9
- $VERBOSE = true
10
- end
11
-
12
4
  def safe_load_round_trip(object, options={})
13
5
  yaml = object.to_yaml
14
6
  if SafeYAML::YAML_ENGINE == "psych"
@@ -32,47 +24,6 @@ describe YAML do
32
24
  SafeYAML.restore_defaults!
33
25
  end
34
26
 
35
- describe "check_libyaml_version" do
36
- REAL_YAML_ENGINE = SafeYAML::YAML_ENGINE
37
- REAL_LIBYAML_VERSION = SafeYAML::LIBYAML_VERSION
38
-
39
- after :each do
40
- silence_warnings do
41
- SafeYAML::YAML_ENGINE = REAL_YAML_ENGINE
42
- SafeYAML::LIBYAML_VERSION = REAL_LIBYAML_VERSION
43
- end
44
- end
45
-
46
- def test_check_libyaml_version(warning_expected, yaml_engine, libyaml_version=nil)
47
- silence_warnings do
48
- SafeYAML.const_set("YAML_ENGINE", yaml_engine)
49
- SafeYAML.const_set("LIBYAML_VERSION", libyaml_version)
50
- Kernel.send(warning_expected ? :should_receive : :should_not_receive, :warn)
51
- SafeYAML.check_libyaml_version
52
- end
53
- end
54
-
55
- it "issues no warnings when 'Syck' is the YAML engine" do
56
- test_check_libyaml_version(false, "syck")
57
- end
58
-
59
- it "issues a warning if Psych::LIBYAML_VERSION is not defined" do
60
- test_check_libyaml_version(true, "psych")
61
- end
62
-
63
- it "issues a warning if Psych::LIBYAML_VERSION is < 0.1.6" do
64
- test_check_libyaml_version(true, "psych", "0.1.5")
65
- end
66
-
67
- it "issues no warning if Psych::LIBYAML_VERSION is == 0.1.6" do
68
- test_check_libyaml_version(false, "psych", "0.1.6")
69
- end
70
-
71
- it "issues no warning if Psych::LIBYAML_VERSION is > 0.1.6" do
72
- test_check_libyaml_version(false, "psych", "1.0.0")
73
- end
74
- end
75
-
76
27
  describe "unsafe_load" do
77
28
  if SafeYAML::YAML_ENGINE == "psych" && RUBY_VERSION >= "1.9.3"
78
29
  it "allows exploits through objects defined in YAML w/ !ruby/hash via custom :[]= methods" do
@@ -31,4 +31,12 @@ require "ostruct"
31
31
  require "hashie"
32
32
  require "heredoc_unindent"
33
33
 
34
+ # Stolen from Rails:
35
+ # https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/kernel/reporting.rb#L10-25
36
+ def silence_warnings
37
+ $VERBOSE = nil; yield
38
+ ensure
39
+ $VERBOSE = true
40
+ end
41
+
34
42
  require File.join(HERE, "resolver_specs")
metadata CHANGED
@@ -1,31 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_yaml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Tao
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-04 00:00:00.000000000 Z
11
+ date: 2014-04-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parse YAML safely
14
14
  email: daniel.tao@gmail.com
15
- executables: []
15
+ executables:
16
+ - safe_yaml
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
19
- - ".gitignore"
20
- - ".travis.yml"
20
+ - .gitignore
21
+ - .travis.yml
21
22
  - CHANGES.md
22
23
  - Gemfile
23
24
  - LICENSE.txt
24
25
  - README.md
25
26
  - Rakefile
27
+ - bin/safe_yaml
26
28
  - bundle_install_all_ruby_versions.sh
27
29
  - lib/safe_yaml.rb
28
30
  - lib/safe_yaml/deep.rb
31
+ - lib/safe_yaml/libyaml_checker.rb
29
32
  - lib/safe_yaml/load.rb
30
33
  - lib/safe_yaml/parse/date.rb
31
34
  - lib/safe_yaml/parse/hexadecimal.rb
@@ -52,6 +55,7 @@ files:
52
55
  - spec/exploit.1.9.3.yaml
53
56
  - spec/issue48.txt
54
57
  - spec/issue49.yml
58
+ - spec/libyaml_checker_spec.rb
55
59
  - spec/psych_resolver_spec.rb
56
60
  - spec/resolver_specs.rb
57
61
  - spec/safe_yaml_spec.rb
@@ -74,17 +78,17 @@ require_paths:
74
78
  - lib
75
79
  required_ruby_version: !ruby/object:Gem::Requirement
76
80
  requirements:
77
- - - ">="
81
+ - - '>='
78
82
  - !ruby/object:Gem::Version
79
83
  version: 1.8.7
80
84
  required_rubygems_version: !ruby/object:Gem::Requirement
81
85
  requirements:
82
- - - ">="
86
+ - - '>='
83
87
  - !ruby/object:Gem::Version
84
88
  version: '0'
85
89
  requirements: []
86
90
  rubyforge_project:
87
- rubygems_version: 2.0.14
91
+ rubygems_version: 2.2.2
88
92
  signing_key:
89
93
  specification_version: 4
90
94
  summary: SameYAML provides an alternative implementation of YAML.load suitable for
@@ -94,6 +98,7 @@ test_files:
94
98
  - spec/exploit.1.9.3.yaml
95
99
  - spec/issue48.txt
96
100
  - spec/issue49.yml
101
+ - spec/libyaml_checker_spec.rb
97
102
  - spec/psych_resolver_spec.rb
98
103
  - spec/resolver_specs.rb
99
104
  - spec/safe_yaml_spec.rb