流行的 PHP CMS 的历史安全漏洞?
Posted
技术标签:
【中文标题】流行的 PHP CMS 的历史安全漏洞?【英文标题】:Historical security flaws of popular PHP CMS's? 【发布时间】:2011-02-26 11:19:45 【问题描述】:我正在创建一个 php CMS,我希望它会被公众使用。安全性是一个主要问题,我想向一些流行的 PHP CMS 学习,如 Wordpress、Joomla、Drupal 等。它们过去有哪些安全缺陷或漏洞,我可以在我的应用程序中避免我可以使用什么策略来避免它们?还有哪些我需要关注的问题,因为他们从一开始就正确处理了这些问题,所以他们可能没有将其视为漏洞?您将包括哪些额外的安全功能或措施,从微小的细节到系统级安全方法? 请尽可能具体。我一般都知道大多数常见的攻击媒介,但我想确保涵盖所有基础,所以不要'不要害怕提及显而易见的事情。假设 PHP 5.2+。
编辑:我将其更改为社区 wiki。即使接受了 Arkh 的出色答案,如果您有更多示例,我仍然对它们感兴趣。
【问题讨论】:
+1 个很好的问题,每个人都知道的特别之处 :) 那里没有足够的 php cms 吗? 应该是社区维基? 我想知道为什么每个人都跳起来投票这样一个无用的问题。它与安全无关。一个人无法从某人的愚蠢错误中学到安全感。安全必须是一个系统,而不是几个补丁。 @Col。 Shrapnel - 也可以随意建议系统级安全方法。在我创建 CMS 时,从架构到微小细节的一切都是建议的公平游戏。 【参考方案1】:跨站请求伪造 (CSRF)
说明:
基本思想是诱使用户访问一个页面,在该页面上,他的浏览器将向您攻击的 CMS 发起 POST 或 GET 请求。
假设您知道由 CMS 提供支持的站点管理员的电子邮件。通过电子邮件向他发送一些有趣的网页,其中包含您想要的任何内容。在此页面中,您将使用 CMS 管理面板使用的数据制作一个表单,以创建新的管理员用户。将这些数据发送到网站管理面板,结果将显示在您网页的隐藏 iframe 中。 瞧,您已经创建了自己的管理员帐户。
如何预防:
通常的方法是在所有表单中生成随机的短期(1500 万到一小时)随机数。当您的 CMS 收到表单数据时,它会首先检查 nonce 是否正常。如果不是,则不使用数据。
CMS 示例:
CMS made simple Joomla! Drupal ModX更多信息:
在wikipedia 页面和OWASP project。
密码存储错误
说明:
想象一下,您的数据库被黑客入侵并发布在类似 wikileak 的网站上。知道您的大部分用户在许多网站上使用相同的登录名和密码,您是否希望他们易于获取?
没有。如果您的数据库数据公开,您需要减轻损失。
如何预防:
第一个想法是散列它们。这是一个坏主意,因为rainbow tables(例如,即使哈希不是 md5 而是 sha512)。 第二个想法:在散列之前添加一个唯一的随机盐,这样黑客就必须暴力破解每个密码。问题是,黑客可以快速计算大量哈希。 因此,当前的想法是让散列密码的速度变慢:您不在乎,因为您不经常这样做。但是当他将每毫秒生成的 1000 个哈希值增加到 1 个时,攻击者会哭。为了简化这个过程,你可以使用一些密码大师开发的库phpass。
CMS 示例:
Joomla! : 盐渍md5 ModX : md5 错字3:cleartext Drupal : 在this discussion 之后切换到 phpass。更多信息:
phpass page。
跨站脚本 (XSS)
说明
这些攻击的目的是让您的网站显示一些脚本,这些脚本将由您的合法用户执行。
你有两种:持久或不持久。第一个通常来自您的用户可以保存的东西,另一个依靠发送的请求给出的参数。这是一个例子,不是持久的:
<?php
if(!is_numeric($_GET['id']))
die('The id ('.$_GET['id'].') is not valid');
?>
现在你的攻击者可以发送像http://www.example.com/vulnerable.php?id=<script>alert('XSS')</script>
这样的链接
如何预防
您需要过滤输出到客户端的所有内容。如果您不想让用户保存任何 html,最简单的方法是使用 htmlspecialchars。但是,当您让他们输出 html(他们自己的 html 或从 bbcode 等其他东西生成的某些 html)时,您必须非常小心。这是一个使用 img 标签的“onerror”事件的旧示例:vBulletin vulnerability。或者你有旧的Myspace's Samy。
CMS 示例:
CMS made simple Mura CMS Drupal ModX更多信息:
您可以查看wikipedia 和OWASP。 ha.ckers 页面上还有很多 XSS 向量。
邮件头注入
说明:
邮件标头由 CRLF (\r\n
) 序列分隔。当您使用一些用户数据发送邮件时(例如将其用于 From: 或 To:),它们可以注入更多标头。这样,他们就可以从您的服务器发送匿名邮件。
如何预防:
过滤标题中的所有 \n
、\r
、%0a
和 %0d
字符。
CMS 示例:
Jetbox CMS更多信息:
Wikipedia 像往常一样是一个好的开始。
SQL 注入
说明:
古老的经典。当您使用直接用户输入形成 SQL 查询时,就会发生这种情况。如果此输入是根据需要精心设计的,则用户可以完全按照自己的意愿进行操作。
如何预防:
简单。不要使用用户输入形成 SQL 查询。使用parameterized queries。 考虑任何不是您自己编码的输入作为用户输入,例如来自文件系统、您自己的数据库或网络服务。
CMS 示例:
Drupal Joomla! ModX Pars CMS更多信息:
Wikipedia 和 OWASP 在这个主题上有非常好的页面。
Http 响应拆分
说明:
与电子邮件标头一样,http 标头由 CLRF 序列分隔。如果您的应用程序使用用户输入来输出标头,他们可以使用它来制作自己的。
如何预防:
与电子邮件一样,在将用户输入中的 \n
、\r
、%0a
和 %0d
字符用作标题的一部分之前,将其过滤掉。你也可以urlencode你的标题。
CMS 示例:
Drake CMS Plone CMS Wordpress更多信息:
我会让你猜测一下,你可以在哪里找到关于这种攻击的大量信息。 OWASP 和 Wikipedia。
会话劫持
说明:
在这个例子中,攻击者想要使用另一个合法(并且希望是经过身份验证的)用户的会话。 为此,他可以更改自己的会话 cookie 以匹配受害者的 cookie,也可以让受害者使用他(攻击者的)自己的会话 id。
如何预防:
这里没有什么是完美的: - 如果攻击者窃取了受害者的cookie,您可以检查用户会话是否与用户IP匹配。但是,如果合法用户使用一些经常更改 IP 的代理,这可能会使您的网站变得无用。 - 如果攻击者让用户使用他自己的会话 ID,只需使用session_regenerate_id 来更改用户在权限更改时的会话 ID(登录、注销、进入网站的管理部分等)。
CMS 示例:
Joomla! 和 Drupal Zen Cart更多信息:
Wikipedia 主题页面。
其他
用户 DoSing :如果您通过禁用尝试过的用户名而不是尝试来自的 IP 来防止暴力破解登录尝试,那么任何人都可以在 200 万内阻止您的所有用户。生成新密码时也是如此:在用户确认新密码之前不要禁用旧密码(例如通过使用它登录)。 使用用户输入在您的文件系统上执行某些操作。过滤这个就像它是癌症和艾滋病一样。这涉及对部分来自用户输入的路径的文件使用 include 和 require。 通过用户输入使用eval、system、exec 或任何此类内容。 不要将您不希望 Web 访问的文件放在 Web 可访问目录中。您可以在OWASP 页面上阅读很多内容。
【讨论】:
稍微改进一下,让更多人可以增强它。 具有讽刺意味的是,您的跨站点脚本示例很容易受到跨站点脚本的攻击。 ;) 哦,是的。抱歉,我没有看它,我只是快速向下滚动并认为它不应该容易受到 XSS 攻击。 :) 会话劫持 - 你提到了 ip 检查,但没有提到用户代理。如果你将用户代理字符串与会话匹配,你当然会得到匹配,但是它确实增加了一点额外的安全层。【参考方案2】:我记得一个来自 phpBB 的相当有趣的。自动登录 cookie 包含一个包含用户 ID 和加密密码(无盐)的序列化数组。将密码更改为值为 true 的布尔值,您就可以以您想成为的任何人身份登录。你不喜欢弱类型语言吗?
phpBB 的另一个问题是在正则表达式中突出显示具有回调(使用e modifier
)的搜索关键字,这使您能够执行自己的 PHP 代码 - 例如,在不安全系统上的系统调用或只需输出配置文件即可获取 mysql 登录名/密码。
总结一下这个故事:
注意 PHP 被弱类型化 (md5( "secretpass" ) == true
)。
小心所有可用于回调(或更糟,eval)的代码。
当然还有我之前已经提到的其他问题。
【讨论】:
【参考方案3】:我看到 CMS 处理的另一个应用程序级安全问题是对页面或功能级访问授权不足。换句话说,通过仅在您有权查看这些链接时显示链接来设置安全性,而不是完全检查用户帐户是否有权查看页面或在页面上后使用该功能。
换句话说,管理员帐户显示了指向用户管理页面的链接。但是用户管理页面只检查用户是否登录,而不是他们登录和管理员。然后,普通用户登录,手动输入管理页面 URI,然后拥有对用户管理页面的完全管理员访问权限,并将其帐户设为管理员帐户。
即使在可以查看用户 CC 数据的购物车应用程序中,我也见过多少次这样的事情,您会感到惊讶。
【讨论】:
【参考方案4】:很多人似乎忘记或没有意识到的最重要的一点是,任何人都可以将任何数据发布到您的脚本中,包括 cookie 和会话等。不要忘记,仅仅因为用户登录,不会不是说他们可以做任何事情。
例如,如果您有一个处理评论添加/编辑的脚本,您可能会有这样的:
if ( userIsLoggedIn() )
saveComment( $_POST['commentid'], $_POST['commenttext'] )
你能看出有什么问题吗?您检查了用户是否已登录,但您没有检查用户是否拥有评论,或者是否能够编辑评论。这意味着任何已登录的用户都可以发布评论 ID 和内容并编辑其他人的 cmets!
向他人提供软件时要记住的另一件事是服务器设置差异很大。发布数据时,您可能希望这样做,例如:
if (get_magic_quotes_gpc())
$var = stripslashes($_POST['var']);
else
$var = $_POST['var'];
【讨论】:
【参考方案5】:这么多..
这里的许多答案是列出他们记得的特定 vuls 或通用的“我在编写 web 应用程序时担心的事情”,但如果你想要一个合理可靠的历史发现的大多数报告漏洞的列表,那么你不会这样做比搜索National Vulnerability Database更糟糕
在 Joomla 或 Joomla 插件中报告了 582 个漏洞,199 个用于 Wordpress,345 个用于 Drupal 供您消化。
对于常见的 webapp vuls 的一般理解,OWASP Top Ten project 最近已更新,是任何 web 开发人员的必备读物。
A1:注射 A2:跨站脚本 (XSS) A3:身份验证和会话管理损坏 A4:不安全的直接对象引用 A5:跨站请求伪造 (CSRF) A6:安全配置错误 A7:不安全的加密存储 A8:未能限制 URL 访问 A9:传输层保护不足 A10:未经验证的重定向和转发【讨论】:
【参考方案6】:我心目中的四大:
对不受信任的数据/代码(或一般情况下)使用 exec 包含来自远程 URL 的文件以供本地执行 启用寄存器全局变量以便获取和发布变量 自动分配变量值。 不转义数据库输入数据/允许 SQL 注入攻击 (通常在不使用 DB API 层时发生)【讨论】:
【参考方案7】:禁止来自其他域/IP 的 POST,因此机器人无法登录/提交表单。
【讨论】:
他不能,因为这很愚蠢。即使他打算检查引用者,也不会阻止任何机器人。 好的,可以通过多种方式实现。我在下面写下一个简单(但松散的方式)。 if($_SERVER['REQUEST_METHOD'] == 'POST' && $_SERVER['HTTP_REFERER']==[ur site URL]) // Alow it is safe else //不允许 但遗憾的是 HTTP_REFERER 很容易被伪造,所以最好在每个表单中使用一些加密的隐藏值,然后在发布时检查验证它。要实现这一点,必须实现一些客户端(JS)。 如果需要,机器人会伪造引用。但是 csrf 是另一回事。 加密的隐藏值也可以发回 如果你有一个由真正的浏览器支持的机器人,那么是的,普通的机器人不能。而且我认为大多数报废机器人都没有浏览器/Js 引擎的支持,所以他们无法真正捕捉到什么正在通过客户端完成。【参考方案8】:人,最大的安全漏洞,是人 愚蠢。 信任,审查代码。你需要一个特别的团队,他们会审查在你的应用程序中添加为额外代码的任何内容,cms 的问题是外包、传入、WordPress、Drupal、Joomla 和其他流行的 cms,就像默认安装一样,它们真的很好点安全。当您让人们在您的应用程序中添加额外代码而没有经过良好审查(或者更好,没有渗透测试)时,问题就来了。这就是 WordPress 和 Joomla 的弱点,有这么多的插件和主题开发者,有这么多的批准,数百个过时的插件和主题......所以恕我直言,如果你能够建立一个强大的团队,一个好的安全计划,培训你的贡献者,并学习他们如何编写安全代码,并且与我之前的所有其他 cmets 一起,然后你将能够继续说:ei hi,这是我的 cms,它更安全一些比网络上的所有其他 cms ;)
【讨论】:
【参考方案9】:对于论坛管理员来说,这是一个潜在的陷阱,对于那些使用下拉选择器编写表单但没有验证发布的回复实际上是可用选项之一的人来说也是如此。
在大学时,我意识到 phpBB 中用户的“国家”选择器没有这样的验证。
在我们的学校论坛中,我的国家可能不是“美国”或“阿富汗”,而是任何东西,无论多么愚蠢或肮脏。我只需要一个 html POST 表单。我的同学们花了几天时间才弄清楚我是怎么做到的,但很快,所有“酷孩子”的用户名下都出现了有趣的短语,而不是国家/地区。
去极客大学真是太棒了。 :D
【讨论】:
以上是关于流行的 PHP CMS 的历史安全漏洞?的主要内容,如果未能解决你的问题,请参考以下文章