如何发送与PHP和jQuery安全AJAX请求如何发送与PHP和jQuery安全AJAX请求(How

2019-05-13 08:10发布

问题

等了一会,现在我一直在尝试用不同的方法AJAX在将数据发送到将要处理和存储在MySQL数据库中的服务器。

该AJAX请求命中页面api.php ,使用PHP的PDO准备语句来保存数据,因此MySQL注射是不是一个真正的问题,需要通过进行加密,也处理的密码或数据api.php这ISN” T I要问这里。 我的问题更多地涉及如何确保数据的安全性,从客户端转移到服务器时。

该方法

我现在有(为登录例如我在下面包括):

  • SSL证书/ HTTPS域上运行。
  • 某些AJAX请求(因为没有会话开始与显然不是这个登录请求例子)如果PHP会议是整个网站(两者使用的有效只会工作login.phpapi.php在这个例子中)。
  • 速率限制api.php访问功能的时候。
  • PHP PDO与内部数据库进行交互时,预处理语句api.php
  • 内部加密敏感数据api.php (的问题不相关)。

问题

最后,我的问题是:

  1. 这是方法使用异步HTTP(阿贾克斯)请求足够的安全使用,而不仅仅是数据提交到一个PHP页面,并开始重定向? (由于这种方式提高了用户体验)。
  2. 如何检查要知道,我的用户正在发送还没有被篡改的数据?
  3. 我是相当采取足够措施来保护我的用户的数据,如果不是,我还能做什么呢?

这个例子

我理解每个人都有不同的方法来处理他们的网站的数据和传输数据。 我也明白,不管你做什么,你永远不可能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"
    });
}

Answer 1:

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.comapi.example.com而是充分https://example.com 。 为什么呢? 因为你可以欺骗这个检查与像api.example.com.hacker.com原点。


2.生成CSRF令牌

一个良好的解释具体到PHP的答案已经给出了那里 ,总之:

  1. 生成令牌:

     session_start(); if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } 
  2. 它添加在通过元(如Github上)你产生看法:

     <meta name="csrf-token" content="<?= $_SESSION['csrf_token'] ?>"> 
  3. 设置jQuery的AJAX调用包括此令牌:

     $.ajaxSetup({ headers : { 'CsrfToken': $('meta[name="csrf-token"]').attr('content') } }); 
  4. 服务器端检查您的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说,这是最基本的一个安全原则 。



Answer 2:

简短的回答:你不能保护你的客户端。

长一点的回答:

  • 使用AJAX只是与发布的数据,例如,一种形式是安全的。
  • 使用HTTPS防止人在这方面的中间人,看看你的用户数据,因此用户实际发送的数据是安全的。

你不能做任何事情来让浏览器证明它实际上是一个在客户端上运行JavaScript代码。 然后,明显的采取的措施是最简单的一个: 永远不要相信用户的输入。

这意味着,当你开始做,使用会话,速率限制,数据验证的fail2ban(禁止一定数量的失败后,客户端IP)保护您的服务器端,日志监控...



Answer 3:

最好的办法还是做服务器端固定,如果我是一个登录的用户在该网站我也能够检查我的meta标签的CSRF令牌和伪造的脚本到服务器。 所以肯定的赌注是服务器端验证



文章来源: How to send secure AJAX requests with PHP and jQuery