<p>Here's a perfect example of the problem: <a href="http://blog.teksol.info/2009/03/27/argumenterror-on-number-sum-when-using-classifier-bayes.html" rel="nofollow noreferrer">Classifier gem breaks Rails</a>.</p>

<p>** Original question: **</p>

<p>One thing that concerns me as a security professional is that Ruby doesn't have a parallel of Java's package-privacy.  That is, this isn't valid Ruby:</p>

<pre><code>public module Foo
  public module Bar
    # factory method for new Bar implementations
    def self.new(...)
      SimpleBarImplementation.new(...)
    end
    def baz
      raise NotImplementedError.new('Implementing Classes MUST redefine #baz')
    end
  end

  private class SimpleBarImplementation
    include Bar
    def baz
      ...
    end
  end
end
</code></pre>

<p>It'd be really nice to be able to prevent monkey-patching of Foo::BarImpl.  That way, people who rely on the library know that nobody has messed with it.  Imagine if somebody changed the implementation of MD5 or SHA1 on you!  I can call <code>freeze</code> on these classes, but I have to do it on a class-by-class basis, and other scripts might modify them before I finish securing my application if I'm not <strong>very</strong> careful about load order.</p>

<p>Java provides lots of other tools for defensive programming, many of which are not possible in Ruby.  (See Josh Bloch's book for a good list.)  Is this really a concern?  Should I just stop complaining and use Ruby for lightweight things and not hope for "enterprise-ready" solutions?</p>

<p>(And no, core classes are not frozen by default in Ruby.  See below:)</p>

<pre><code>require 'md5'
# =&gt; true
MD5.frozen?
# =&gt; false
</code></pre>

[{'answer_id': 32471, 'author': 'Gishu', 'author_id': 1695, 'author_profile': 'https://Stackoverflow.com/users/1695', 'pm_score': 1, 'selected': False, 'text': '<p>I guess Ruby has that a feature - valued more over it being a security issue.  Ducktyping too.<br>\nE.g. I can add my own methods to the Ruby String class rather than extending or wrapping it.</p>\n'}, {'answer_id': 33611, 'author': 'Jörg W Mittag', 'author_id': 2988, 'author_profile': 'https://Stackoverflow.com/users/2988', 'pm_score': 3, 'selected': False, 'text': '<p>I don\'t think this is a concern.</p>\n\n<p>Yes, the mythical "somebody" can replace the implementation of MD5 with something insecure. But in order to do that, the mythical somebody must actually be able to get his code into the Ruby process. And if he can do that, then he presumably could also inject his code into a Java process and e.g. rewrite the bytecode for the MD5 operation. Or just intercept the keypresses and not actually bother with fiddling with the cryptography code at all.</p>\n\n<p>One of the typical concerns is: I\'m writing this awesome library, which is supposed to be used like so:</p>\n\n<pre><code>require \'awesome\'\n# Do something awesome.\n</code></pre>\n\n<p>But what if someone uses it like so:</p>\n\n<pre><code>require \'evil_cracker_lib_from_russian_pr0n_site\'\n# Overrides crypto functions and sends all data to mafia\nrequire \'awesome\'\n# Now everything is insecure because awesome lib uses \n# cracker lib instead of builtin\n</code></pre>\n\n<p>And the simple solution is: don\'t do that! Educate your users that they shouldn\'t run untrusted code they downloaded from obscure sources in their security critical applications. And if they do, they probably deserve it.</p>\n\n<p>To come back to your Java example: it\'s true that in Java you can make your crypto code <code>private</code> and <code>final</code> and what not. However, someone can <em>still</em> replace your crypto implementation! In fact, someone actually did: many open-source Java implementations use OpenSSL to implement their cryptographic routines. And, as you probably know, Debian shipped with a broken, insecure version of OpenSSL for years. So, all Java programs running on Debian for the past couple of years actually <em>did</em> run with insecure crypto!</p>\n'}, {'answer_id': 33648, 'author': 'Orion Edwards', 'author_id': 234, 'author_profile': 'https://Stackoverflow.com/users/234', 'pm_score': 2, 'selected': False, 'text': '<blockquote>\n  <p>Java provides lots of other tools for defensive programming</p>\n</blockquote>\n\n<p>Initially I thought you were talking about <a href="http://en.wikipedia.org/wiki/Defensive_programming#Some_Defensive_programming_techniques" rel="nofollow noreferrer">normal defensive programming</a>, \nwherein the idea is to defend the program (or your subset of it, or your single function) from invalid data input.<br>\nThat\'s a great thing, and I encourage everyone to go read that article.</p>\n\n<p>However it seems you are actually talking about "defending your code from other programmers."  </p>\n\n<p>In my opinion, this is a completely pointless goal, as no matter what you do, a malicious programmer can always run your program under a debugger, or use <a href="http://en.wikipedia.org/wiki/DLL_injection" rel="nofollow noreferrer">dll injection</a> or any number of other techniques.</p>\n\n<p>If you are merely seeking to protect your code from incompetent co-workers, this is ridiculous. <strong>Educate your co-workers, or get better co-workers.</strong></p>\n\n<p>At any rate, if such things are of great concern to you, ruby is not the programming language for you. Monkeypatching is in there by design, and to disallow it goes against the whole point of the feature.</p>\n'}, {'answer_id': 33900, 'author': 'James A. Rosen', 'author_id': 1190, 'author_profile': 'https://Stackoverflow.com/users/1190', 'pm_score': 1, 'selected': False, 'text': '<p>"Educate your co-workers, or get better co-workers" works great for a small software startup, and it works great for the big guns like Google and Amazon.  It\'s ridiculous to think that every lowly developer contracted in for some small medical charts application in a doctor\'s office in a minor city.</p>\n\n<p>I\'m not saying we should build for the lowest common denominator, but we have to be realistic that there are <em>lots</em> of mediocre programmers out there who will pull in any library that gets the job done, paying no attention to security.  How <em>could</em> they pay attention to security?  Maybe the took an algorithms and data structures class.  Maybe they took a compilers class.  They almost certainly didn\'t take an encryption protocols class.  They definitely haven\'t all read Schneier or any of the others out there who practically have to <em>beg and plead</em> with even very good programmers to consider security when building software.</p>\n\n<p>I\'m not worried about this:</p>\n\n<pre><code>require \'evil_cracker_lib_from_russian_pr0n_site\'\nrequire \'awesome\'\n</code></pre>\n\n<p>I\'m worried about <code>awesome</code> requiring <code>foobar</code> and <code>fazbot</code>, and <code>foobar</code> requiring <code>has_gumption</code>, and ... eventually two of these conflict in some obscure way that undoes an important security aspect.</p>\n\n<p>One important security principle is "defense in depth" -- adding these extra layers of security help you from accidentally shooting yourself in the foot.  They can\'t completely prevent it; nothing can.  But they help.</p>\n'}, {'answer_id': 161268, 'author': 'Grant Hutchins', 'author_id': 6304, 'author_profile': 'https://Stackoverflow.com/users/6304', 'pm_score': 2, 'selected': True, 'text': '<p>Check out <a href="http://scie.nti.st/2008/9/17/making-methods-immutable-in-ruby" rel="nofollow noreferrer">Immutable</a> by Garry Dolley.</p>\n\n<p>You can prevent redefinition of individual methods.</p>\n'}, {'answer_id': 161278, 'author': 'Alex', 'author_id': 24420, 'author_profile': 'https://Stackoverflow.com/users/24420', 'pm_score': 1, 'selected': False, 'text': '<p>If monkey patching is your concen, you can use the Immutable module (or one of similar function). </p>\n\n<p><a href="http://gilesbowkett.blogspot.com/2008/09/monkey-patch-which-prohibits-monkey.html" rel="nofollow noreferrer">Immutable</a></p>\n'}, {'answer_id': 161295, 'author': 'Lars Westergren', 'author_id': 15627, 'author_profile': 'https://Stackoverflow.com/users/15627', 'pm_score': 1, 'selected': False, 'text': '<p>You could take a look at Why the Lucky Stiff\'s "Sandbox"project, which you can use if you worry about potentially running unsafe code.\n<a href="http://code.whytheluckystiff.net/sandbox/" rel="nofollow noreferrer">http://code.whytheluckystiff.net/sandbox/</a></p>\n\n<p>An example (online TicTacToe):\n<a href="http://www.elctech.com/blog/safely-exposing-your-app-to-a-ruby-sandbox" rel="nofollow noreferrer">http://www.elctech.com/blog/safely-exposing-your-app-to-a-ruby-sandbox</a></p>\n'}, {'answer_id': 297991, 'author': 'Tetha', 'author_id': 17663, 'author_profile': 'https://Stackoverflow.com/users/17663', 'pm_score': 0, 'selected': False, 'text': '<p>If someone monkeypatched an object or a module, then you need to look at 2 cases: He added a new method. If he is the only one adding this meyhod (which is very likely), then no  problems arise. If he is not the only one, you need to see if both methods do the same and tell the library developer about this severe problem.</p>\n\n<p>If they change a method, you should start to research why the method was changed. Did they change it due to some edge case behaviour or did they actually fix a bug? especially in the latter case, the monkeypatch is a god thing, because it fixes a bug in many places.</p>\n\n<p>Besides that, you are using a very dynamic language with the assumption that programmers use this freedom in a sane way. The only way to remove this assumption is not to use a dynamic language. </p>\n'}, {'answer_id': 331458, 'author': 'James A. Rosen', 'author_id': 1190, 'author_profile': 'https://Stackoverflow.com/users/1190', 'pm_score': 1, 'selected': False, 'text': '<p>Raganwald has a <a href="http://github.com/raganwald/homoiconic/tree/master/2008-12-1/keep_your_privates_to_yourself.md" rel="nofollow noreferrer">recent post</a> about this.  In the end, he builds the following:</p>\n\n<pre><code>class Module\n  def anonymous_module(&amp;block)\n   self.send :include, Module.new(&amp;block)\n  end\nend\n\nclass Acronym\n  anonymous_module do\n    fu = lambda { \'fu\' }\n    bar = lambda { \'bar\' }\n    define_method :fubar do\n      fu.call + bar.call\n    end\n  end\nend\n</code></pre>\n\n<p>That exposes <code>fubar</code> as a public method on <code>Acronym</code>s, but keeps the internal guts (<code>fu</code> and <code>bar</code>) private and hides helper module from outside view.</p>\n'}]
['https://Stackoverflow.com/questions/32333', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1190/']