如果我对php脚本进行AJAX调用,就像这样(使用jQuery)
$.ajax(url: "../myscript.php");
Run Code Online (Sandbox Code Playgroud)
并且myscript看起来是这样的:
<?php
//code that does something to db
?>
Run Code Online (Sandbox Code Playgroud)
我想知道如何防止用户只是去example.com/myscript.php来执行脚本.
每个XmlHTTP请求都可以重放和篡改(只需检查您最喜欢的浏览器控制台,捕获POST或GET请求并检查是否有重播选项),您还可以尝试Live HTTP Headers模块(或更多)并捕获任何内容进行重放它.
因此,如果您在应用程序中设置了一个入口点,那么任何人都可以尝试访问它并在那里注入一些不好的东西.
请注意,他们还可以更改其请求中的任何HTTP标头,以更改引用页面或主机标头等任何内容.
因此,在安全性方面,每个用户输入都必须被认为是不安全的(GET参数,POST数据,使用过的url - OMG,因此很多应用程序永远不会过滤来自url路径的数据 - ,cookies,......)
所以你可能想知道"我怎么能用不安全的输入做些什么?",嗯......你可以.规则是过滤所有输出.获取输出管道(数据库存储,html页面,json响应,csv文件)并相应地转义数据(htmlentites用于HTML,json转义为json,sql escaper或参数化查询用于SQL查询 - 检查libs--),尤其是来自用户输入的部件,如前所述,实际上是不安全的.
现在您的主要问题是访问控制,您有一个入口点,您可以在其中执行某些数据库操作,并且您不希望任何人访问此入口点并执行操作.
有几件事要做:
现在,如果您应该运行的"数据库"内容与任何用户权限无关,但您只是想防止滥用它,例如统计ajax查询,执行计数器增量,每个用户应至少调用一次.在这种情况下,您将遇到一些问题.很难防止滥用公共入口点(只考虑保护网站免受DOS和DDOS的困扰).您必须构建一个基于应用程序的功能系统,例如在用户页面中生成唯一令牌并检查此令牌仅使用一次(但是来自代理的数千个用户可以使用匿名页面)缓存),也许你必须记录用户IP并通过IP限制令牌使用(但是一些用户可能共享相同的IP),或者你可能必须使用ajax将唯一令牌发送给用户.
我们可以谈论很多事情,但这取决于你想要做的事情.重要的是:
这里的一些答案让您概述了您的问题背后的概念,让我给您一个更务实的方法(您至少应该阅读并理解其他人对此事的看法!)。
您只需要问自己:您的应用程序是否必须强制控制对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!
//...
})
Run Code Online (Sandbox Code Playgroud)
然后在你的脚本中:
<?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
Run Code Online (Sandbox Code Playgroud)
否则,您只需检查用户是否已登录,就像通常处理其余脚本一样:
<?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
Run Code Online (Sandbox Code Playgroud)
总结
使用第一种方法可以实现更受控的访问,因为您强制用户发送普通用户不会拥有的秘密(令牌,在每个请求中都不同)(如果其他用户获得了令牌,那么您就拥有了更大的问题,例如会话劫持)。请注意,此方法可防止用户在多个选项卡/不同浏览器上打开,因为只会保存最后一个令牌。为了避免你对SO有这个很棒的答案
另一方面,第二种方法允许(已登录)用户直接请求您的myscript.php,但也许您不需要阻止这种情况(如果需要,只需使用第一种方法)。请注意,这里您不会遇到多个选项卡/不同浏览器的问题,因为您只会检查用户是否已登录。
| 归档时间: |
|
| 查看次数: |
1171 次 |
| 最近记录: |