2010-07-15 32 views
3

我一直在研究一个应用程序,该应用程序允许构建第三方扩展来扩展应用程序的功能。当然,所有这些都在PHP中。我想通过校验和功能在特定目录中运行文件来添加一些安全填充。如果文件未通过校验和,则文件不被“包含”,通知该安装的管理员,并且该模块被禁用,直到管理员采取行动(重新启用并记录该异常或重新安装模块) 。包含之前的PHP校验和()

我现在遇到的问题是无论何时用户运行include()函数都可以运行该校验和。我宁愿不让他们为了包含一个文件而背靠背运行两个函数,但是如果必须的话,我会的。并非所有的第三方扩展都会非常愿意运行两个函数(类似于if(checksum_function($bleh)) include($bleh);),即使它们是,执行include()时运行校验和会更容易(也更安全),而不是双倍行数为include()报表。

我已经做了一些搜索,并没有找到太多。想法?提前致谢!

回答

0

如果您的includes包括以某个系统命名的类(例如MyPlugin_Text),那么您可以使用PHP的autoloading。自动加载可用于在首次创建类的对象时自动包含文件。

极其简单的例子:

function __autoload($class_name) { 

    require_once $class_name . '.php'; 
} 

$myTextPlugin = new MyPlugin_Text(); 

显然,你会想要扩展自动加载,如仅对从MyPlugin_开始的类进行预加载,并加载来自特定文件夹的预加载。

除了编写自定义包装函数之外,我知道没有其他方法可以实现您想要执行的操作。

我喜欢你的想法。然而,计算校验和 - 例如使用crc32() - 相对昂贵。不应该有太多,也不会太大,包括这种方式加载。另外,如果攻击者能够修改系统中的PHP文件,他们也可以直接执行它们,而不需要您的中央应用程序。此练习的实际安全收益可能很小。

+0

crc碰撞可以使用代数来计算。 – rook 2010-07-15 07:24:07

+0

感谢Pekka。我打算为我的校验和使用md5,但我想这会更加昂贵。我没有想过使用__autoload()。我可能会放弃这个想法,因为一旦实施其他一切,实际上可能会非常昂贵。不过,我肯定会玩一些__autoload()。谢谢! – Swivel 2010-07-15 07:32:38

+0

@您认为恶意脚本修复该文件是否意味着它通过了检查?在大多数情况下,我认为这不会成为一种危险,因为如果攻击者a)知道安全机制并且b)可以在相关网络空间上写入文件,则无论如何都会丢失。不过,好点。 – 2010-07-15 07:33:02

0

考虑写一个包装为include

function include_safe($library) { 
    if(checksum_function($library)) 
     include($library); 
} 

你不会找到许多开发商是“快乐”使用的特点就是这样,但你也不能重写PHP语言结构(如includerequire)。具有包装所有内容的功能方便快捷,因此开发人员可能会使用它。

+0

你的目的是什么校验和?你如何去验证这个校验和与你想包含的东西有关?那么我会使用这个函数'make_everything_secure_ever()',然后没有人会攻击我。你不想知道这个功能是干什么的吗? @ – rook 2010-07-23 00:18:25

+1

@Rook OP正在寻找解决方案的适当语法,而不是安全实现。事实上,如果你真的要阅读这个问题,OP甚至提供了“checksum_function”的名字。对我来说更合适的答案是建议OP使用装饰器,尽管他们很遗憾在PHP中不存在。我可以理解你是痛苦的,但孩子气地投票下来的答案,并留下公然无知的评论是我称之为“不专业”。 – mattbasta 2010-07-23 16:46:59

+0

谢谢mattbasta。 – Swivel 2010-07-27 05:07:50

0

在许多移动代码平台中,通常会看到使用RSA Digital Signature签名的可执行代码。这允许授权机构“确定”一段可以分发第三方的代码,并且客户知道代码是安全的。数字签名用于帮助防止现代控制台视频游戏的盗版。它们也用于验证软件更新来自供应商,而不是攻击者。

这个php应用程序可以有公钥(甚至可以用这个公钥分发)。管理员可以访问公钥和私钥,使用它可以签署一个.php文件。在包括签名可以被检查。如果php文件被修改或损坏,签名将不会通过检查。

在实践中,PHP应用程序执行很多包含,因此任何验证功能都将是一个巨大的瓶颈。任何安全的东西也将非常昂贵。最好检查一次签名,然后将其传送到白名单目录或数据库。另一种提高速度的方法是使用较小的RSA密钥进行签名。例如,对于SSLv3,一个512位的RSA密钥足够好,所以它可能足够好。

MD5是非常糟糕的。如果您存储“安全”md5文件哈希的白名单,那么这将打开collision generation的大门。这是使用md5前缀攻击的理想情况,因为特制的二进制数据在文件的开始处不会阻止include()执行php标记<?php ?>内的代码。

CRC比MD5更糟。 CRC不打算使散列冲突更加困难。 CRC只是为了检测随机噪声造成的损害。通过将数据a附加到消息a CRC collision can be generated对md5使用类似的攻击。

sha1是一个安全且快速的哈希函数,您可以使用。有一个类似的哈希碰撞攻击影响sha1。然而,与md5不同,没有人生成sha1 collsion和NIST still considers its use to be safe。虽然sha256会是更安全的选择。

+0

谢谢。我一直在考虑使用sha256公钥和私钥。我已经实施了公钥和私钥。公钥存储在公共存储库中,在下载和安装时检查密钥。安装完成后,将为每个实例生成一个新的私钥,并检查其是否完整。 SHA1原本是我心目中的,但默认为md5。我想这对我来说是天真的,尤其是考虑到我对md5最近缺乏完整性的了解。我将使用SHA256作为密钥,如果我最终实现了校验和,我将使用SHA1。 – Swivel 2010-07-16 05:42:24

+0

再次感谢您的答案。我喜欢公钥和私钥的想法,但是我有点犹豫,因为如果我能够以经济高效的方式对文件运行校验和,那么我会更喜欢这种方式。我会坚持使用SHA-HASH算法。但是,鉴于我的应用程序的口径,RSA密钥签名会有点多! :P – Swivel 2010-07-16 05:46:44

0

我想检查每个负载的校验和是一个坏主意,因为它会为你的应用程序肯定放慢。

一种不同的方法是,你把东西在你的应用程序管理界面安装或启用该插件。

然后,你可以检查插件一次安装时,并将其添加到启用插件列表,然后才能使用它。

你也可以查看每天一次所有的插件,以检查是否一个被改变......但它很难做出安全的,因为任何改变插件,而它被安装也可以改变你的安全功能。