如何保护PHP脚本?

时间:2014-08-17 22:07:34

标签: php security web

如果我对php脚本进行AJAX调用,就像这样(使用jQuery)

$.ajax(url: "../myscript.php");

myscript看起来像这样:

<?php
    //code that does something to db
 ?>

我想知道如何阻止用户访问example.com/myscript.php来执行脚本。

3 个答案:

答案 0 :(得分:8)

Ajax查询只是用户查询

每个XmlHTTP请求都可以重播和篡改(只需检查您喜欢的浏览器控制台,捕获POST或GET请求并检查是否有重播选项),您也可以尝试Live HTTP Headers模块(或更多)并捕捉任何东西来重播它。

因此,如果您在应用程序中设置了一个入口点,任何人都可以尝试访问它并在那里注入一些不好的东西。

请注意,他们还可以更改其请求中的任何HTTP标头,以更改引用页面或主机标头等内容。

不安全的输入

因此,在安全性方面,每个用户输入都必须被视为不安全(GET参数,POST数据,使用过的网址 - OMG这么多应用程序永远不会过滤数据到来来自网址路径 - ,cookies,...)

过滤输出

所以你可能想知道&#34;我怎样才能用不安全的输入做些事情?&#34;嗯......你可以。规则是过滤所有输出。取输出通道(数据库存储,html页面,json响应,csv文件)和相应地转义数据(htmlentites用于HTML,json转义用于json,sql escaper或用于SQL查询的参数化查询 - 检查libs--),特别是来自用户输入的部分,如前所述,它们实际上是不安全的。

访问控制

现在您的主要问题是访问控制,您有一个入口点,您可以在其中执行某些数据库操作,并且您不希望任何人访问此入口点并执行操作。

要做的几件事:

  • 确保这不是GET入口点(只有POST,PUT,DELETE HTTP操作应该对数据库执行修改),这样可以防止在以后在图像标记中使用此URL,在没有用户交互的情况下加载操作。
  • 使用Cookie管理用户会话(PHP为您做到了这一点)您可以在多个HTTP请求之间共享一些数据,这称为会话。用户cookie将用于加载服务器端会话存储,其中包含重要数据,例如我的用户是匿名用户还是已连接的用户?。这是标识部分。
  • 管理登录注销页面以获取身份验证部分,这些页面将以登录状态提供会话。对于一个简单的解决方案,您还可以检查HTTP基本身份验证(.htpasswd文件),它也适用于ajax,但从不使用没有SSL的HTTP基本身份验证。此Http身份验证模式将管理身份识别和身份验证部分。
  • 以您希望的方式管理 ACL (访问控制列表),并使用它来决定当前用户是否可以访问您的ajax页面(您从会话中获取用户)。如果没有,请发送403 HTTP响应。

公共访问

现在,如果你的数据库&#39;应该运行的东西与任何用户权限无关,但你只是想防止滥用它,比如统计ajax查询,做一个计数器增量,每个用户应至少调用一次。在这种情况下,您将遇到一些问题。要防止滥用公共入口点是非常困难的(只要想想保护DOS和DDOS网站有多难)。您必须构建一个基于应用程序的功能系统,例如在用户页面中生成唯一令牌并检查此令牌仅使用一次(但成千上万的用户可以使用匿名页面,来自代理缓存),也许您必须记录用户IP并通过IP限制令牌使用(但某些用户可能共享相同的IP),或者您可能必须将唯一令牌发送给用户使用ajax。

我们可以谈论很多事情,但这取决于你要做的事情。重要的是:

  • 永远不信任用户输入
  • 过滤输出
  • 管理会话和ACL
  • 从不认为任何隐藏的东西,没有这样的东西。

答案 1 :(得分:3)

这里的一些答案让你概述了问题背后的概念,让我给你一个更务实的方法(你至少应该阅读并理解其他人对此事的看法!)。

您只需要问自己:您的应用是否必须强制执行对 myscript.php 的所有请求?

如果那么您需要使用某种令牌:您创建令牌并将其发送到客户端(浏览器),然后浏览器必须发回令牌并检查它是否匹配在做一些动作之前:

<?php
// somefile.php (this file serves the page that contains your AJAX call)
session_start();
//...
$_SESSION['token'] = createNewToken(); // creates unique tokens

//add the token as a JS variable and send it back in your AJAX CALL
// some where you'll have something similar to this:
<script>
  var token = <?php echo $_SESSION['token'] ?>;
  $.ajax({
    url: "myscript.php",
    data: form_data, // include the token here!
    //...
  })

然后在你的剧本中:

<?php
// myscript.php
session_start();

// you can check if it's an AJAX call, if the user is logged and then the token:    
if (!isset($_SESSION['token')) {
  header("HTTP/1.0 403 Forbidden");
  die("Direct access not allowed!");
}

// Assuming your AJAX is a POST though you didn't tell us
if (!isset($_POST['token'] || $_POST['token'] != $_SESSION['token']) {
  header("HTTP/1.0 400 Bad request");
  die("You didn't provide a valid token!");
}

// do something with your DB

否则您只需要检查用户是否按照正常情况对其余脚本进行了记录:

<?php
// myscript.php
session_start();
// Check if logged in user
if (!isset($_SESSION['loggedIn']) || !$_SESSION['loggedIn']) {
  header("HTTP/1.0 403 Forbidden");
  die("You need to be logged in!");
}

// Do something with your DB

整理

使用第一种方法允许更加受控的访问,因为您强制用户发送一个普通用户不会拥有的秘密(令牌,在每个请求中都会有所不同)(如果某个其他用户获得了令牌,然后你有更大的问题,如会话劫持)。请注意,此方法会阻止用户在多个选项卡/不同浏览器上打开,因为只保存最后一个标记。为了避免你有this fantastic answer on SO

另一方面,第二种方法允许(已记录)用户直接请求您的 myscript.php ,但也许您不需要阻止(如果您需要,只需使用)第一种方法)。请注意,您不会遇到多个标签/不同浏览器的问题,因为您只会检查用户是否已登录。

答案 2 :(得分:1)

  

如何阻止用户访问example.com/myscript.php来执行脚本

从安全角度来看,AJAX调用与用户访问该URL的相同。也就是说,用于进行AJAX调用的人类用户和脚本是同一安全主体的一部分。如果您不信任有权访问PHP脚本的用户,则您无法信任在用户控制的计算机上运行的JavaScript。

那么在什么情况下可以有单独的安全主体?例如,您可以仅在某种防篡改信息亭上部署客户端JavaScript。这样,您可以在服务器中存储一个秘密值,与服务器共享。信息亭将发送秘密值,每次请求服务器进行验证。

但如果您出于可用性原因这样做,为了防止意外调用脚本,那么,也许尝试Dirk Pitt所关联的一件事。