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


    PHP 中的安全性

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

    漏洞类型

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

    • Cross Site Request Forgery由于程序员没有检查请求从哪里发送而导致的应用程序中的一个漏洞——这种攻击被发送给高权限级别的用户以获得对应用程序的更高级别的访问权限。
    • 跨站脚本程序员在将输入输出到浏览器之前没有清理输入(例如博客上的评论)导致的应用程序漏洞。它通常用于在浏览器中运行恶意 javascript 来进行攻击,例如窃取会话 cookie 以及其他恶意操作,以在应用程序中获得更高级别的权限。
    • 本地文件包含由程序员需要用户提供的文件输入并且在访问请求的文件之前未清理输入而导致的应用程序漏洞。这会导致文件被包含在不应该包含的位置。
    • 远程文件包含由程序员需要用户提供的文件输入并且在访问请求的文件之前未对输入进行清理而导致的应用程序漏洞。这会导致从远程服务器中提取文件并将其包含在不应该存在的位置。
    • 会话劫持攻击者获得对用户会话标识符的访问权并能够使用另一个用户的帐户来冒充他们而导致的漏洞。这通常用于访问管理用户的帐户。
    • Session Identifier Acquirement Session Identifier Acquirement 是攻击者能够猜测用户的会话标识符或利用应用程序本身或用户浏览器中的漏洞获取会话标识符而导致的漏洞。
    • SQL 注入由程序员在将输入包含到数据库查询之前未清理输入而导致的应用程序漏洞。这导致攻击者拥有对数据库的完全读取权限,并且往往没有写入权限。通过这种类型的访问,攻击者可以做非常糟糕的事情。

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

    会话劫持

    会话劫持是由攻击者获得对用户会话标识符的访问权并能够使用另一个用户的帐户来冒充他们而导致的漏洞。这通常用于访问管理用户的帐户。

    防御 PHP 中的会话劫持攻击

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

    1. session_start();
    2. // Does IP Address match?
    3. if ($_SERVER['REMOTE_ADDR'] != $_SESSION['ipaddress'])
    4. {
    5. session_unset();
    6. session_destroy();
    7. }
    8. // Does user agent match?
    9. if ($_SERVER['HTTP_USER_AGENT'] != $_SESSION['useragent'])
    10. {
    11. session_unset();
    12. session_destroy();
    13. }
    14. // Is the last access over an hour ago?
    15. if (time() > ($_SESSION['lastaccess'] + 3600))
    16. {
    17. session_unset();
    18. session_destroy();
    19. }
    20. else
    21. {
    22. $_SESSION['lastaccess'] = time();
    23. }

    跨站脚本

    Cross Site Scripting 是 Web 应用程序中的一种漏洞,由程序员在将输入输出到 Web 浏览器(例如博客上的评论)之前没有清理输入而导致。它通常用于在 Web 浏览器中运行恶意 javascript 来进行攻击,例如窃取会话 cookie 等恶意行为,以在 Web 应用程序中获得更高级别的权限。

    跨站点脚本攻击示例

    博客允许用户使用 HTML 标签设置他们的评论样式,但是支持博客的脚本不会去除标签,

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

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

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

    1. $usercomment = "alert('Cross Site Scripting!');";
    2. echo htmlspecialchars($usercomment);

    另一种方法是strip_tags($string, $allowedtags)删除除您列入白名单的 HTML 标记之外的所有 HTML 标记的函数。请务必注意,使用该strip_tags()功能时您必须更加小心,此功能不会阻止用户将 javascript 作为链接包含在内,您必须自行对其进行清理。

    strip_tags() 代码示例

    1. $usercomment = "alert('Cross Site Scripting!');";
    2. $allowedtags = "

      ";

    设置 X-XSS-Protection 标头:

    在 PHP 中,您可以发送X-XSS-ProtectionHeader,它会告诉浏览器检查反射的跨站点脚本攻击并阻止页面加载。这并不能阻止所有的跨站点脚本攻击,只是反射攻击,应该与其他方法结合使用。

    1. header("X-XSS-Protection: 1; mode=block");

    编写自己的清理函数如果您想更好地控制清理工作的方式,另一种选择是编写自己的 HTML 清理函数,不建议 PHP 初学者这样做,因为错误会使您的网站易受攻击。

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

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

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

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

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

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

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

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

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

    1. "Content-Security-Policy" content="default-src 'self'; img-src https://*; child-s

    SQL 注入

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

    示例 SQL 注入攻击

    下面的 PHP 脚本运行一个 SQL 语句以通过 ID 获取用户的电子邮件。但是输入没有经过过滤,使其容易受到 SQL 注入的影响

    1. $input = $_GET['id'];
    2. $dbserver = "localhost";
    3. $dbuser = "camper";
    4. $dbpass = "supersecretcampsitepassword";
    5. $dbname = "freecodecamp";
    6. $conn = new mysqli($dbserver, $dbuser, $dbpass, $dbname);
    7. if ($conn->connect_error) {
    8. die("Connection failed: " . $conn->connect_error);
    9. }
    10. $sql = "SELECT email FROM users WHERE id =" . $input;
    11. $result = $conn->query($sql);
    12. if ($result->num_rows > 0) {
    13. while($row = $result->fetch_assoc()) {
    14. echo $row["email"];
    15. }
    16. } else {
    17. echo "no results";
    18. }
    19. $conn->close();
    SELECT email FROM users WHERE id = `$input`;
    

    因此,上面的输入不是类型转换的(即用 (int) 转换输入,所以只允许一个数字)也不是转义允许某人执行 SQL 注入攻击 - 例如,URLgetemailbyuserid.php?id=1'; My Query Here-- -将允许您运行任意 SQL 查询一点点努力。

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

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

    白名单:白名单方法用于只需要少量输入的情况。您可以在 PHP Switch 中列出每个预期的输入,然后为无效输入设置默认值。您不必担心类型转换问题或字符转义绕过,但允许的输入非常有限。它仍然是一个选项,请参见下面的示例。

    1. switch ($input) {
    2. case "1":
    3. //db query 1
    4. break;
    5. case "2":
    6. //db query 2
    7. break;
    8. default:
    9. // invalid input return error
    10. }

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

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

    更多关于 PHP:

  • 相关阅读:
    旋转框目标检测mmrotate v0.3.1入门
    c++视觉----使用多边形包围轮廓
    驱动开发--汇总
    音视频进阶教程-实现直播SEI补充增强信息
    学习数据结构和算法的第8天
    RabbitMQ消息队列高级特性
    SpringCloud的新闻资讯项目00--- 项目功能演示
    React native新架构组成
    【LeetCode】【剑指offer】【复杂链表的复制】
    C/C++数据结构之深入了解树与二叉树:概念、存储结构和遍历
  • 原文地址:https://blog.csdn.net/allway2/article/details/126101801