这里是一个完美的例子的问题: 分类的宝石打破轨.

**原来的问题:**

有一件事涉及我作为一个安全专业人员是红宝石不会有一个平行的Java包隐私。也就是说,这不是有效的红宝石:

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

这会是真的高兴能够防止猴子-修补的Foo::BarImpl.这样,人依赖的图书馆知道,没有人搞砸了它。想象一下,如果有人改变了执行MD5或SHA1你!我可以打电话 freeze 在这些课程,但是我必须这样做在一个类的基础上,和其他的脚本可能会修改他们之前我完成保护我的应用程序,如果我不是 非常 小心负荷的顺序。

Java提供了大量的其他工具,用于防御性的节目,其中许多都是不可能的红宝石。(见乔希布洛克的书的一个好的名单。) 这真是一个问题吗?我是不是应该停止抱怨和使用红宝石重量轻的东西并不希望对"企业"的解决方案?

(不,核心课程是不冻结默认情况下,在红宝石。看到下面:)

require 'md5'
# => true
MD5.frozen?
# => false
有帮助吗?

解决方案

检查了 不可改变的 通过加里Dolley.

你可以防止重新界定个别方法。

其他提示

我不认为这是一个令人关切。

是的,神秘的"有人"可以替换的执行情况MD5的东西不安全。但为了做到这一点,神话中的某人实际上必须能够得到他的密码进入红宝石的过程。如果他可以这样做,然后他大概也可以注射,他的代码转Java过程和例如重写字节的MD5操作。或者只是拦截按键和实际上不是打扰乱动的加密代码。

一个典型的关切问题是:我写这真棒图书馆,这是应该用于这样的:

require 'awesome'
# Do something awesome.

但是,如果有人使用它,像这样:

require 'evil_cracker_lib_from_russian_pr0n_site'
# Overrides crypto functions and sends all data to mafia
require 'awesome'
# Now everything is insecure because awesome lib uses 
# cracker lib instead of builtin

而简单的解决方案是:不要这样!教育你的用户,他们不应该运行不受信任的代码,他们从掩盖源于他们的安全的关键应用程序。如果他们这样做,他们可能应该得到它。

回到你的Java例如:这是真的,在Java你可以做你的密码 privatefinal 和什么不可以。然而,有人可以 仍然 替你加密的执行!事实上,有人实际所做的:许多开放源码Java实现使用OpenSSL来实现他们的加密程序。而且,正如你可能知道,Debian附带一个破碎、不安全的版本OpenSSL for年。因此,所有Java上运行的程序Debian在过去的几年里实际上 有没有 运行不安全的加密!

Java提供了大量的其他工具可用于防御编程

起初我以为你们是在谈论 正常的防御编程, 其中的想法是保卫程序(或者你的子集,或单一的功能)来自无效的数据输入。
这是一个伟大的事情,并且我鼓励大家去读那篇文章。

然而,它似乎你们实际上谈论的是"保卫你的代码从其他程序员。"

在我看来,这是一个完全没有意义的目标,因为不管你做什么,一个恶意程序总是可以运行程序下一个调试器,或者使用 dll注射 或任何数目的其他技术。

如果你仅仅是寻求以保护你的代码从不称职的同事,这是荒谬的。 教育你的同事,或获得更好的同事。

无论如何,如果这样的事情都非常关注你的红宝石并不是编程语言。Monkeypatching是在有通过设计,并不允许它违背整点的功能。

我想红宝石有一个特点值更正在一个安全问题。Ducktyping。
E.g。我可以加入我自己的方法的红宝石串类,而不是延伸或包装。

"教育你的同事,或获得更好的共同工人"的伟大工程,对一个小型软件的启动,以及它的伟大工程大炮,如谷歌和亚马逊。它是荒唐的认为,每一个卑微的开发商签订合同在对一些小型医疗图应用程序在医生的办公室在一个小城市。

我不是说我们应该建立最低共同点,但我们必须要现实,还有 很多 平庸的程序员有谁会拉在任何库获取的完成工作,而不重视安全。如何 可能 他们注意到安全吗?也许拿了一种算法和数据结构类。也许他们把一个编译器类。他们几乎可以肯定没有采取一种加密协议类。他们肯定还没有读Schneier或任何其他人在那里实际上有 乞求与辩护 甚至有非常良好的程序要考虑安全当建立软件。

我担心的不是这样的:

require 'evil_cracker_lib_from_russian_pr0n_site'
require 'awesome'

我很担心 awesome 需要 foobarfazbot, , foobar 需要 has_gumption, 和...最终两个这些冲突在一些模糊的方式,撤消一个重要的安全方面。

一个重要的安全原则是"纵深防御"--加入这些额外的层次的安全帮助你从不小心搬起石头砸自己的脚。他们不能完全防止;没有什么可以。但他们的帮助。

如果猴子修补是你的concen,可以使用不可改变的模块(或一项类似的功能)。

不可改变的

你可以看一看为什么的幸运硬的"沙箱"的项目,该项目可以使用如果你担心潜在的运行不安全的代码。http://code.whytheluckystiff.net/sandbox/

一个实例(在线井字游戏):http://www.elctech.com/blog/safely-exposing-your-app-to-a-ruby-sandbox

Raganwald有一个 最近的文章 关于这一点。最后,他建如下:

class Module
  def anonymous_module(&block)
   self.send :include, Module.new(&block)
  end
end

class Acronym
  anonymous_module do
    fu = lambda { 'fu' }
    bar = lambda { 'bar' }
    define_method :fubar do
      fu.call + bar.call
    end
  end
end

这暴露了 fubar 作为一个公共的方法 Acronyms,但保留的内部胆量(fubar)私人和隐藏的辅助模块从外面查看。

如果有人monkeypatched对象或模块,然后你需要看看2情况:他加入一个新方法。如果他是唯一一个加入这meyhod(这是非常可能),则没有出现问题。如果他不是唯一一个,你需要看到如果这两种方法这样做和告诉库的开发有关这一严重问题。

如果他们改变方法,你应该开始研究为什么的方法是更改。他们有没有改变它由于某些边缘情况下的行为或没有实际上,他们修正一个错误?特别是在后一种情况下,monkeypatch是上帝的事情,因为它修正了一个错误,在很多地方。

除此之外,你使用一个非常动态的语言的假设,编程人员使用这种自由在一个理智的方式。唯一的方法来消除这种假设是不使用一个动态的语言。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top