PHP安全漏洞:会话劫持,跨站点脚本,SQL注入以及如何修复它们

本文摘自:freeCodeCamp

PHP中的安全性

在编写PHP代码时,记住以下安全漏洞非常重要,以避免编写不安全的代码。

漏洞类型

这些是编写PHP代码时会遇到的常见漏洞。我们将在下面进一步深入讨论。

  • 跨站点请求伪造程序员未检查发送请求的位置而导致的应用程序中的漏洞-此攻击被发送给高特权级别的用户,以获取对该应用程序的更高级别的访问权限。
  • 跨站点脚本(Cross Site Scripting)应用程序中的一个漏洞,是由程序员在将输入输出到浏览器之前未对输入进行消毒(例如,对博客的评论)。它通常用于在浏览器中运行恶意javascript进行攻击,例如在其他恶意操作中窃取会话cookie,以在应用程序中获得更高级别的特权。
  • 包含本地文件由程序员要求用户提供文件输入并且在访问请求的文件之前不清除输入内容导致的应用程序中的漏洞。这将导致文件不应包含在其中。
  • 包含远程文件由程序员要求用户提供文件输入并且在访问请求的文件之前不清除输入内容引起的应用程序中的漏洞。这会导致文件从远程服务器中拉出,并包含在不应包含的位置。
  • 会话劫持(Session Hijacking)由攻击者获得对用户会话标识符的访问权,并能够使用其他用户的帐户来模拟它们的漏洞。这通常用于获得对管理用户帐户的访问权限。
  • 会话标识符获取会话标识符获取是由攻击者能够猜测用户的会话标识符或利用应用程序本身或用户的浏览器中的漏洞获取会话标识符引起的漏洞。
  • SQL注入SQL注入是应用程序中的一个漏洞,由程序员在将输入包含到数据库中的查询之前未对输入进行清理。这导致攻击者具有对数据库的完全读取权限,并且经常具有对数据库的不写入权限。通过这种访问方式,攻击者可以做非常坏的事情。

现在,让我们更详细地了解一些常见漏洞。

会话劫持

会话劫持是由攻击者获得对用户会话标识符的访问权,并能够使用其他用户的帐户来模拟它们的漏洞。这通常用于获得对管理用户帐户的访问权限。

防御PHP中的会话劫持攻击

为了防御会话劫持攻击,您需要根据存储的有关会话的信息检查当前用户的浏览器和位置信息。下面是一个示例实现,可以帮助减轻会话劫持攻击的影响。它会检查IP地址,用户代理以及会话是否过期,然后再恢复会话。

<?php
session_start();

// Does IP Address match?
if ($_SERVER['REMOTE_ADDR'] != $_SESSION['ipaddress'])
{
session_unset();
session_destroy();
}

// Does user agent match?
if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['useragent'])
{
  session_unset();
  session_destroy();
}

// Is the last access over an hour ago?
if (time() > ($_SESSION['lastaccess'] + 3600))
{
  session_unset();
  session_destroy();
}
else
{
  $_SESSION['lastaccess'] = time();
}

跨站脚本

跨站点脚本编制是Web应用程序中的一种漏洞,它是由程序员在将输入输出到Web浏览器之前(例如,对博客的评论)未清理输入而引起的。它通常用于在Web浏览器中运行恶意javascript进行攻击,例如在其他恶意操作中窃取会话cookie,以在Web应用程序中获得更高级别的特权。

跨站点脚本攻击示例

博客允许用户使用HTML标记来设置其注释样式,但是为博客提供动力的脚本不会删除<script>标记,允许任何用户在页面上运行javascript。攻击者可以利用此漏洞来在浏览器中运行恶意javascript。他们可能用恶意软件感染用户,窃取会话Cookie等。

<script>
  alert('Cross Site Scripting!');
</script>

保护您的网站免受PHP中的跨站点脚本攻击

在PHP中,有两个主要功能htmlspecialchars()strip_tags()内置,以保护自己免受跨站点脚本攻击。

htmlspecialchars($string)功能将阻止HTML字符串呈现为HTML,并将其作为纯文本显示给Web浏览器。htmlspecialchars()代码示例

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
echo htmlspecialchars($usercomment);

另一种方法是strip_tags($string, $allowedtags)删除除已列入白名单的HTML标记之外的所有HTML标记的函数。重要的是要注意,strip_tags()您必须更加谨慎地使用该函数,该函数不会阻止用户将javascript作为链接包含在内,因此您必须自行进行清理。

strip_tags()代码示例

<?php
$usercomment = "<string>alert('Cross Site Scripting!');</script>";
$allowedtags = "<p><a><h1><h2><h3>";
echo strip_tags($usercomment, $allowedtags);

设置X-XSS-Protection标头:

在PHP中,您可以发送X-XSS-Protection标头,该标头将告诉浏览器检查是否反映了跨站点脚本攻击,并阻止页面加载。这不能防止所有跨站点脚本攻击仅反映出来,因此应与其他方法结合使用。

<?php
header("X-XSS-Protection: 1; mode=block");

编写自己的清理功能如果要对清理的工作方式进行更多控制,另一种选择是编写自己的HTML清理功能,PHP初学者不建议这样做,因为这样会使您的网站容易受到攻击。

使用内容安全策略保护您的网站免受跨站点脚本攻击

防止跨站点脚本攻击的一种有效方法是使用内容安全策略,这种攻击可能需要对Web应用程序的设计和代码库进行大量调整。

将内容安全策略设置为HTTP标头

设置内容安全策略的最常见方法是直接在HTTP标头中进行设置。这可以由Web服务器通过编辑其配置或通过PHP发送来完成。

HTTP标头中设置的内容安全策略的示例

<?php
header("content-security-policy: default-src 'self'; img-src https://*; child-src 'none';");

将内容安全策略设置为元标记

您可以将内容安全策略包含在页面的HTML中,并逐页进行设置。此方法要求您在每个页面上进行设置,否则将失去该策略的好处。

在HTML元标记中设置的内容安全策略的示例

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-s

SQL注入

SQL注入是应用程序中的一个漏洞,它是由程序员在将输入包含到数据库中的查询之前没有对输入进行清理而引起的。这导致攻击者具有对数据库的完全读取权限,并且经常具有对数据库的不写入权限。通过这种访问方式,攻击者可以做非常坏的事情。

示例SQL注入攻击

下面的PHP脚本运行一个SQL语句,以按ID获取用户的电子邮件。但是,输入没有经过清理,因此容易受到SQL注入的攻击

<?php
$input = $_GET['id'];
$dbserver = "localhost";
$dbuser = "camper";
$dbpass = "supersecretcampsitepassword";
$dbname = "freecodecamp";

$conn = new mysqli($dbserver, $dbuser, $dbpass, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$sql = "SELECT email FROM users WHERE id =" . $input;

$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["email"];
    }
} else {
    echo "no results";
}

$conn->close();
SELECT email FROM users WHERE id = `$input`;

因此,使用上述方法,输入不会进行类型转换(即,使用(int)转换输入,因此只允许输入数字),也无法进行转义以允许某人执行SQL Injection攻击-例如,URLgetemailbyuserid.php?id=1'; My Query Here-- -允许您使用以下命令运行任意SQL查询一点努力。

保护您的网站免受PHP中的SQL注入攻击

有几种方法可以保护您的网站免受SQL Injection Attacks的攻击。这些方法是白名单,类型转换和字符转义

白名单:白名单方法用于只需要少量输入的情况。您可以在PHP Switch中列出每个期望的输入,然后为无效输入提供默认值。您不必担心类型转换问题或字符转义旁路,但是允许的输入受到极大限制。它仍然是一个选项,请参见下面的示例。

<?php
switch ($input) {
  case "1":
    //db query 1
    break;
  case "2":
    //db query 2
    break;
  default:
    // invalid input return error
}

类型转换:类型转换方法通常用于使用数字输入的应用程序。只需将输入转换为(int) $input,则只允许使用数字值。

字符转义:字符转义方法将转义用户提供的引号和斜杠等字符,以防止攻击。如果使用MySQL Server和MySQLi库访问数据库,则该mysqli_real_escape_string($conn, $string)函数将使用两个参数,即MySQLi连接和字符串,并将正确地转义用户的输入以阻止sql注入攻击。您使用的确切功能取决于您使用的数据库类型和php库,请查阅php库的文档以获取有关转义用户输入的更多信息。

阅读原文

本文来自投稿,不代表微擎百科立场,如若转载,请注明出处:https://www.w7.wiki/develop/4455.html

发表评论

登录后才能评论