前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用HTTP Headers防御WEB攻击

使用HTTP Headers防御WEB攻击

作者头像
黄啊码
发布2020-05-29 16:06:57
8540
发布2020-05-29 16:06:57
举报

搭建试验环境

数据以及实验环境下载地址在文末!

你可以在XAMPP、WAMP、LAMP、MAMP下设置PHP-MYSQL应用,当然这个选择完全取决于你的喜好。

在本实验中,我使用的是搭载MAMP的苹果Mac机器,我把所以文件都放在了根目录下的“sample”文件夹内。

应用程序功能介绍

设置完这个实验样品之后,打开主页

http://localhost/sample/index.php

从上图中我们看以看到,这个页面就是一个简单的登录页面,它会进行基本的服务端验证。

用户输入字段不能为空,完成这个功能只需使用PHP的empty()函数。因此用户如果不输入点东西点击登录,会返回下面这个页面

如果输入的用户名密码不匹配的话,会返回以下页面,当然完成这一步骤是需要执行数据库查询操作的。

输入的用户密码正确,主页显示用户已登录。

如下所示,这是使用MySQLi准备语句完成的。

代码语言:javascript
复制
$stmt = $mysqli->prepare("select * from admin where username=? and password=?");
$stmt->bind_param("ss",$username,$password);
$stmt->execute(); 
username: admin
password: 1q2w3e4r5t

注意:在这个示例中,给定的密码以SHA1算法方式存储在数据库中,这个密码使用在线工具可以轻松解出来。

登录进去之后会看到一个表单,这个表单含有一个简单的Xss漏洞。

现在我们进行抓包,当我们登陆时注意观察默认的Header信息。

在成功登录之后我们看到一个搜索框,这里接受用户输入并返回相关信息给用户。

下面是构建登录后页面的代码

代码语言:javascript
复制
<?php
session_start();
session_regenerate_id();
if(!isset($_SESSION['admin_loggedin']))
{
    header('Location: index.php');
}
 
 if(isset($_GET['search']))
{
    if(!empty($_GET['search']))
    {
        $text = $_GET['search'];
    }
    else
    {
        $text = "No text Entered";
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Admin Home</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
 
         <div id="home"><center>
        </br><legend><text id=text><text id="text2">Welcome to Dashboard...</text></br></br> You are logged in as: <?php echo $_SESSION['admin_loggedin']; ?> <a href="logout.php">[logout]</a></text></legend></br>
        <form action="" method="GET">
            <div id="search">
            <text id="text">Search Values</text><input type="text" name="search" id="textbox"></br></br>
 
             <input type="submit" value="Search" name="Search" id="but"/>
 
             <div id="error"><text id="text2">You Entered:</text><?php echo $text; ?></div>
 
             </div>
        </form></center>
    </div>
 
     </body>
</html>

使用X-Frame-Options响应头防御点击劫持

首先我们要讨论的就是使用X-Frame-Options缓解点击劫持

通常,攻击者在漏洞页面嵌入iframe标签执行点击劫持攻击。

在我们这个实验中,会在用户管理页面中加载一个iframe标签,如下所述。

成功登录之后会进入http://localhost/sample/home.php页面

代码语言:javascript
复制
<!DOCTYPE html>
<html>
    <head>
        <title>iframe</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <iframe src="http://localhost/sample/home.php"></iframe>
    </body>
</html>

在同一台服务器上,我将此页面保存为iframe.html。在浏览器中加载home页面的同时也会加载这个iframe

虽然有多钟方案来防御此问题,但是本文是讨论X-Frame-Options响应头这种方案。

X-Frame-Options有以下3个值可以使用。

代码语言:javascript
复制
DENY:表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN:表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM:表示该页面可以在指定来源的 frame 中展示。

X-Frame-Options: DENY

让我们先从X-Frame-Options: DENY开始

打开home.php文件,添加下面这一行

代码语言:javascript
复制
header(“X-Frame-Options: DENY”);

修改后的代码如下

代码语言:javascript
复制
<?php
session_start();
session_regenerate_id();
 
 header("X-Frame-Options: DENY");
 
 if(!isset($_SESSION['admin_loggedin']))
{
    header('Location: index.php');
}
 
 if(isset($_GET['search']))
{
    if(!empty($_GET['search']))
    {
        $text = $_GET['search'];
    }
    else
    {
        $text = "No text Entered";
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Admin Home</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
 
         <div id="home"><center>
        </br><legend><text id=text><text id="text2">Welcome to Dashboard...</text></br></br> You are logged in as: <?php echo $_SESSION['admin_loggedin']; ?> <a href="logout.php">[logout]</a></text></legend></br>
        <form action="" method="GET">
            <div id="search">
            <text id="text">Search Values</text><input type="text" name="search" id="textbox"></br></br>
 
             <input type="submit" value="Search" name="Search" id="but"/>
 
             <div id="error"><text id="text2">You Entered:</text><?php echo $text; ?></div>
 
             </div>
        </form></center>
    </div>
 
     </body>
</html>

从网页中退出后重新登录观察HTTP头信息

得到如下头信息

如果你注意到,在响应信息中出现了一个X-Frame-Options

现在我们重新加载iframe,是得不到任何显示的

使用Chrome的开发者模式,我们来看看背后隐藏的秘密。

在Firefox中使用开发者模式

在Firefox中加载iframe.html页面,下面是控制台提示的错误信息

X-Frame-Options: SAMEORIGIN

有可能存在需要使用框架的情景。在此类情况下,就可以使用SAMEORIGIN值

打开home.php文件并添加如下代码

代码语言:javascript
复制
header(“X-Frame-Options: sameorigin”);\

修改后代码如下

代码语言:javascript
复制
<?php
session_start();
session_regenerate_id();
 
 header("X-Frame-Options: sameorigin");
 
 if(!isset($_SESSION['admin_loggedin']))
{
    header('Location: index.php');
}
if(isset($_GET['search']))
{
    if(!empty($_GET['search']))
    {
        $text = $_GET['search'];
    }
    else
    {
        $text = "No text Entered";
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Admin Home</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
 
         <div id="home"><center>
        </br><legend><text id=text><text id="text2">Welcome to Dashboard...</text></br></br> You are logged in as: <?php echo $_SESSION['admin_loggedin']; ?> <a href="logout.php">[logout]</a></text></legend></br>
        <form action="" method="GET">
            <div id="search">
            <text id="text">Search Values</text><input type="text" name="search" id="textbox"></br></br>
 
             <input type="submit" value="Search" name="Search" id="but"/>
 
             <div id="error"><text id="text2">You Entered:</text><?php echo $text; ?></div>
 
             </div>
        </form></center>
    </div>
 
     </body>
</html>

从网页退出后重新登录,注意观察HTTP头信息

接下来,看看他们不同的工作原理

第一步加载相同的iframe.html,从下图中可以看出加载没有问题

我使用虚拟机打开Kali Linux并把文件放入其中,然后加载这个URL(http://localhost/sample/home.php)

当我们打开iframe.html文件时,由于跨域**而不能正常加载

在浏览器的错误信息中可以看到

错误信息表明了,不允许进行跨域。

X-Frame-Options: ALLOW-FROM http://www.site.com

X-Frame-Options: ALLOW_FROM选项,表示该页面可以在指定来源的 frame 中展示,该选项只适用于IE,Firefox浏览器。

首先打开home.php文件添加如下代码

代码语言:javascript
复制
header(“X-Frame-Options: ALLOW-FROM http://localhost”);

修改后代码如下:

代码语言:javascript
复制
<?php
session_start();
session_regenerate_id();
header("X-Frame-Options: ALLOW-FROM http://localhost");
if(!isset($_SESSION['admin_loggedin']))
{
    header('Location: index.php');
}
if(isset($_GET['search']))
{
    if(!empty($_GET['search']))
    {
        $text = $_GET['search'];
    }
    else
    {
        $text = "No text Entered";
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Admin Home</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
 
         <div id="home"><center>
        </br><legend><text id=text><text id="text2">Welcome to Dashboard...</text></br></br> You are logged in as: <?php echo $_SESSION['admin_loggedin']; ?> <a href="logout.php">[logout]</a></text></legend></br>
        <form action="" method="GET">
            <div id="search">
            <text id="text">Search Values</text><input type="text" name="search" id="textbox"></br></br>
 
             <input type="submit" value="Search" name="Search" id="but"/>
 
             <div id="error"><text id="text2">You Entered:</text><?php echo $text; ?></div>
 
             </div>
        </form></center>
    </div>
 
     </body>
</html>

退出网页,重新登录,观察HTTP头

如果我们现在尝试从同一个服务器加载iframe,网页不会出现任何错误

这是因为服务器允许加载http://localhost 这个地址

现在我们修改HTTP头,再加载

在home.php文件中添加

代码语言:javascript
复制
header(“X-Frame-Options: ALLOW-FROM http://www.androidpentesting.com”);

修改后代码如下

代码语言:javascript
复制
<?php
session_start();
session_regenerate_id();
header("X-Frame-Options: ALLOW-FROM http://www.androidpentesting.com");
if(!isset($_SESSION['admin_loggedin']))
{
    header('Location: index.php');
}
if(isset($_GET['search']))
{
    if(!empty($_GET['search']))
    {
        $text = $_GET['search'];
    }
    else
    {
        $text = "No text Entered";
    }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Admin Home</title>
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
 
         <div id="home"><center>
        </br><legend><text id=text><text id="text2">Welcome to Dashboard...</text></br></br> You are logged in as: <?php echo $_SESSION['admin_loggedin']; ?> <a href="logout.php">[logout]</a></text></legend></br>
        <form action="" method="GET">
            <div id="search">
            <text id="text">Search Values</text><input type="text" name="search" id="textbox"></br></br>
 
             <input type="submit" value="Search" name="Search" id="but"/>
 
             <div id="error"><text id="text2">You Entered:</text><?php echo $text; ?></div>
 
             </div>
        </form></center>
    </div>
 
     </body>
</html>

以下为抓包获取的HTTP头信息

刷新之前的页面,不会加载iframe了

以下为返回的错误信息

很明显http://localhost 是没有获取许可的

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-07-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档