1. 7
  1.  

  2. 4

    Lisp’s boast is that Code is Data. Ruby accidentally and regrettably allowed Data to become Code. Oops.

    Huh? That’s not what’s happening - a deserialization method that allows DOSing isn’t allowing data to become code. It’s just an unsafe function.

    While I agree that you don’t want complex functions that are difficult to audit facing the public interwebs, the entire reason I like using Ruby is because it “gives me too much power.” Ruby is a language designed for small teams of good programmers. If you want something that takes away power from the developer (and thus will always increase development time), use Java.

    1. 5

      the entire reason I like using Ruby is because it “gives me too much power.”

      I don’t think the author is saying Ruby is too powerful. I think they’re saying the two problems observed here:

      • writing a YAML parser that automatically recognizes !-directives and turns the contents into arbitrary Ruby classes
      • writing an XML parser that automatically recognizes <id type="yaml"> tags and parses the contents as YAML

      have the same underlying problem: Rubyists in 2013 had written libraries that were more powerful than they needed to be, and thus had vulnerabilities one wouldn’t expect the libraries to have.

      Lisp’s boast is that Code is Data. Ruby accidentally and regrettably allowed Data to become Code. Oops.

      Huh? That’s not what’s happening - a deserialization method that allows DOSing isn’t allowing data to become code. It’s just an unsafe function.

      Both things are happening, actually. (Or, at least, were happening in 2013.) That there are lots of DOS attacks against XML parsers is generally true of XML parsers, but not the main point. The problem that prompted the article is that Ruby’s XML parser, in 2013, would parse embedded YAML; and Ruby’s YAML parser would interpret YAML ! directives as intended Ruby classes. So a payload like the one below would result in remote code execution. (CVE-2013-0156)

      <id type="yaml">
      ---
      !ruby/object:Gem::Requirement
      requirements:
        - !ruby/object:Rack::Session::Abstract::SessionHash
            env:
              HTTP_COOKIE: "a=#{payload}"
            by: !ruby/object:Rack::Session::Cookie
              coder: !ruby/object:Rack::Session::Cookie::Base64::Marshal {}
              key: a
              secrets: []
            exists: true
      </id>
      
      1. 1

        Comparison with lisp is not by accident, it’s the same “lisp vs unix” discourse, “The Right Thing vs Worse is better”, modernist design vs postmodernist design.

        Fortunately, Ruby (and Rails too) is in the middle of this spectrum. On one extreme side we have Perl, on other side Clojure. Rails (which defines much of Ruby culture) is slowly moving towards modernist side in recent times because it’s in fashion now. I impatiently wait for times when Perl approaches will be in fashion again.