问题
等了一会,现在我一直在尝试用不同的方法AJAX在将数据发送到将要处理和存储在MySQL数据库中的服务器。
该AJAX请求命中页面api.php
,使用PHP的PDO准备语句来保存数据,因此MySQL注射是不是一个真正的问题,需要通过进行加密,也处理的密码或数据api.php
这ISN” T I要问这里。 我的问题更多地涉及如何确保数据的安全性,从客户端转移到服务器时。
该方法
我现在有(为登录例如我在下面包括):
- SSL证书/ HTTPS域上运行。
- 某些AJAX请求(因为没有会话开始与显然不是这个登录请求例子)如果PHP会议是整个网站(两者使用的有效只会工作
login.php
和api.php
在这个例子中)。 - 速率限制
api.php
访问功能的时候。 - PHP PDO与内部数据库进行交互时,预处理语句
api.php
。 - 内部加密敏感数据
api.php
(的问题不相关)。
问题
最后,我的问题是:
- 这是方法使用异步HTTP(阿贾克斯)请求足够的安全使用,而不仅仅是数据提交到一个PHP页面,并开始重定向? (由于这种方式提高了用户体验)。
- 如何检查要知道,我的用户正在发送还没有被篡改的数据?
- 我是相当采取足够措施来保护我的用户的数据,如果不是,我还能做什么呢?
这个例子
我理解每个人都有不同的方法来处理他们的网站的数据和传输数据。 我也明白,不管你做什么,你永远不可能100%的保护,因为有可能是在你的系统漏洞的方式,你无法解释。 我在发送数据的安全,而不是下面的特定代码的批评寻找反馈/改进我的一般方法,因为它仅仅是一个例子。 但是,任何有建设性的答案,欢迎。 感谢您抽出时间来阅读/答案的时间。
function loginUser() {
var process = "loginUser";
var data = $("form").serializeArray();
data[1].value = SHA512(data[1].value); // sha then encrypt on api.php page
data = JSON.stringify(data);
$("#loginButton").html('<i class="fa fa-spinner fa-pulse fa-lg fa-fw"></i> Login');
$.ajax({
type: "POST",
url: "api.php",
data: {"process": process, "data": data},
success: function(data) {
if (data.response.state == "success") {
// if api.php returns success, redirect to homepage
} else {
// if api.php returns failure, display error
}
},
error: function(jqXHR, textStatus, errorThrown, data) {
// error handling
},
dataType: "json"
});
}
1.检查ORIGIN头
作为由OWASP规定 ,这是不够的,但建议:
虽然这是微不足道的,从你自己的浏览器欺骗任何头,一般是不可能的CSRF攻击这样做,除了通过XSS漏洞。 这就是为什么检查头在你的CSRF防御合理的第一步,但由于它们并不总是存在,其通常不被认为是对自己有足够的防御。
而由Mozilla :
Origin标头被认为是对JSON数据窃取和CSRF攻击很有帮助。 由产地提供的信息 - 有点上下文请求创建信息 - 应该提供提示,Web服务器的请求左右守信[...]
检查HTTP_ORIGIN
头可以写成:
header('Content-Type: application/json');
if (isset($_SERVER['HTTP_ORIGIN'])) {
$address = 'http://' . $_SERVER['SERVER_NAME'];
if (strpos($address, $_SERVER['HTTP_ORIGIN']) !== 0) {
exit(json_encode([
'error' => 'Invalid Origin header: ' . $_SERVER['HTTP_ORIGIN']
]));
}
} else {
exit(json_encode(['error' => 'No Origin header']));
}
1.(双)检查REFERER头
再从OWASP :
如果原产头不存在 ,请验证Referer标头的主机网站的起源相匹配。 检查引荐是防止在嵌入式网络设备CSRF,因为它不要求每个用户状态.. CSRF缓解该方法也通常与未认证的请求使用的常用的方法[...]
检查HTTP_REFERER
也是PHP中非常简单$_SERVER['HTTP_REFERER']
你可以用它更新上面的代码。
小心检查它总是需要真正明确:做任何检查只是example.com或api.example.com而是充分https://example.com 。 为什么呢? 因为你可以欺骗这个检查与像api.example.com.hacker.com原点。
2.生成CSRF令牌
一个良好的解释具体到PHP的答案已经给出了那里 ,总之:
生成令牌:
session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); }
它添加在通过元(如Github上)你产生看法:
<meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?>">
设置jQuery的AJAX调用包括此令牌:
$.ajaxSetup({ headers : { 'CsrfToken': $('meta[name="csrf-token"]').attr('content') } });
服务器端检查您的AJAX请求:
session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } header('Content-Type: application/json'); $headers = apache_request_headers(); if (isset($headers['CsrfToken'])) { if ($headers['CsrfToken'] !== $_SESSION['csrf_token']) { exit(json_encode(['error' => 'Wrong CSRF token.'])); } } else { exit(json_encode(['error' => 'No CSRF token.'])); }
大多数PHP框架都有自己的CSRF实现中,在相同的原则,或多或少躺着。
3。 消毒 验证用户输入。
你必须始终 过滤 协商的输入和验证它们 。
4.保护您的服务器
- 限制你的请求数 。
- 使用HTTPS尽可能 。
- 阻止坏的查询 。
- 保护POST请求 。
5.不要相信用户的输入
正如@ blue112说,这是最基本的一个安全原则 。
简短的回答:你不能保护你的客户端。
长一点的回答:
- 使用AJAX只是与发布的数据,例如,一种形式是安全的。
- 使用HTTPS防止人在这方面的中间人,看看你的用户数据,因此用户实际发送的数据是安全的。
你不能做任何事情来让浏览器证明它实际上是一个在客户端上运行JavaScript代码。 然后,明显的采取的措施是最简单的一个: 永远不要相信用户的输入。
这意味着,当你开始做,使用会话,速率限制,数据验证的fail2ban(禁止一定数量的失败后,客户端IP)保护您的服务器端,日志监控...
最好的办法还是做服务器端固定,如果我是一个登录的用户在该网站我也能够检查我的meta标签的CSRF令牌和伪造的脚本到服务器。 所以肯定的赌注是服务器端验证