PHP脚本安全

2020年12月29日16:00:44 发表评论 34 次浏览

使用PHP脚本, 安全性方面基本上集中在两点上:防止跨站点脚本(CSS或XSS)和防止数据嗅探或代码渗透。为了提供足够的保护, 有必要检查脚本处理的所有外部数据。这包括URL中提供的数据, 表单数据, Cookie和上载的文件。

请注意:

这里提到的安全预防措施清单不应被视为完整的清单, 而应用于发现一些基本风险。

安全概念必须考虑所有可能导致潜在漏洞的因素。保护脚本只是整个概念的一个组成部分。

使用include()函数插入代码

一个常见的漏洞是包括()函数与可变参数一起使用。在这种情况下, 攻击者可以通过传递URL作为参数来注入外部代码(例如http://evil-site.tld/exploit.txt)。然后, 将这些代码或URL视为脚本的一部分而执行。避免使用变量值调用include()并使用常量而不是变量。如果不可避免要使用变量, 请相应地过滤其内容。例如, 可以使用以下代码完成此操作。

if (strpos($variable, '://') !== FALSE || strpos($variable, '../') !== FALSE)
die('Illegal string');

此代码检查$变量字符串包含://(如http://orftp://), 要么../(如../../秘密/密码), 并在必要时终止执行。

SQL注入

当脚本使用数据库查询时, 如果脚本不包含某些安全检查, 则攻击者相对容易注入任意SQL代码。这使潜在的攻击者可以读取, 更改甚至删除数据。

假设你在脚本中使用以下代码:

[...]
$sql = "SELECT * FROM adressen WHERE name='".$_GET['name']."'";
$result = mysql_query($sql);
[...]

如果要从包含地址的表中过滤出特定名称的地址, 则可能会出现此查询或类似查询。

攻击者现在可以访问包含执行查询代码的PHP页面, 并注入其他SQL命令。如果包含SQL查询代码的页面是" select.php", 而你的网站是" example.com", 则攻击者可能会将以下URL放入浏览器中并注入SQL命令:http://example.com/select.php?name=';从地址为1 = 1或名称='的地址删除.

这导致SQL查询SELECT * FROM地址WHERE name ='';从地址为1 = 1或名称=''的地址删除;.

首先, 数据库服务器选择所有记录, 名称字段包含一个空字符串。这绕过了脚本的预期目的。然后, 注入的命令从表中删除所有记录。攻击者还可能使用这种类型的漏洞来读取或更改数据库中的数据。

为了防止这种情况, SQL查询中的变量应始终使用mysql_real_escape_string()功能。特殊字符(例如单引号)被屏蔽, 因此它们不会被解释为PHP或SQL代码的一部分。如果将值传递到引号之外(例如数字值), 请使用intval()如果可能的话。这样可确保仅实际使用一个数值。

URL中的参数传递

在网址中传递参数(例如http://example.com/script.php?id=1)是将参数传递给脚本的一种常用方法。但是, 你应该始终意识到, 用户可以随意设置这些参数。这意味着必须将其内容视为不可信任。同样适用于通过HTTP邮件和cookie传输的数据。

从一个脚本重定向到另一个脚本并在URL中或作为cookie传递参数时, 这一点很重要。新脚本不能将这些参数视为可信赖的, 而必须再次检查它们。通常, 使用会话功能PHP。现在可以将已检查并存储在会话中的数据分类并用作安全数据。用户无法直接更改会话的内容。

会话标识符作为URL的参数传递。由于这是随机生成的字符串, 因此攻击者可以猜测外部会话的标识符的可能性非常低。

全局变量

在旧版本的PHP中, 将从表单或URL中传递的参数输入到全局变量中。但是, 出于兼容性的原因, 当前版本在大多数系统上仍会重现此行为。

例如, 如果网址

http://example.com/script.php?variable=content

被称为一个名为

$变量

和内容

内容

在脚本中设置。

如果你在内部使用全局变量而未事先正确初始化它们, 这可能会成为问题。

例子:

<?php
if ($_GET['password'] == 'secretpassword') {
$admin = true;
}

[...]

if ($admin) {
// Actions reserved for an administrator who knows the password.
[...]
}
?>

攻击者只需调用URLhttp://example.com/script.php?admin=1并立即拥有管理员权限, 因为该变量$管理员退货true.

通过正确的初始化, 可以避免这种情况。

<?php
$admin = false;

if ($_GET['password'] == 'secretpassword') {
$admin = true;
}

[...]

if ($admin) {
// Actions reserved for an administrator who knows the password.
[...]
}
?>

现在的价值$管理员一开始始终设置为false, 仅设置为true如果密码实际上已经通过。

在其他情况下, 省略初始化也可以用于SQL注入。因此, 你应该习惯于初始化所有变量, 尽管PHP的语法不需要这样做。

跨站脚本

跨站点脚本编写是攻击者在外部站点中插入JavaScript代码以获得敏感信息的地方。这可以用来访问其他会话ID或确定用户名.

为此, 攻击者创建一个URL, 在其中他设置可以立即在页面文本中显示的参数。如果此文本现在包含脚本代码, 则在页面的安全上下文中执行该脚本代码, 例如它可以读取此页面设置的cookie。这种攻击的危险在于, 当它发生在隐藏的框架中时, 用户几乎看不见它。

解决方案是对所有要输出的变量(尤其是包含用户输入的变量)使用脚本中的htmlentities()函数。这将替换HTML中具有特殊含义的字符, 例如<or>, 以及相应的实体。通过这种简单的措施, 你可以消除跨站点脚本编写的大多数攻击可能性。


一盏木

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: