【问题标题】:XMLHttpRequests, POST data custom headers and verificationXMLHttpRequests、POST 数据自定义标头和验证
【发布时间】:2012-01-02 03:19:14
【问题描述】:

我正在寻求反馈。我一直在尝试找到一种验证客户端发送的 POST 数据并遇到 Content-MD5 标头的好方法。

这是我的解决方案,第一部分是以简单易用的插件形式使用jQuery .ajax() 函数。对于 Content-MD5 标头所需的 md5() 和 base64_encode() 函数,它确实需要 pidder encryption libraries

<script src="javascripts/pidcrypt.js"></script>
<script src="javascripts/pidcrypt_util.js"></script>
<script src="javascripts/md5.js"></script>
<script>
(function($){
 $.fn.AJAX = function(method) {
  var defaults = {
   formID: $(this),
   appID: 'jQuery.AJAX',
   cache: true,
   context: $(this),
   type: 'json',
   callback: function(){},
   errCallback: function(){}
  };
  var methods = {
   init: function(o){
    var opts = $.extend({}, defaults, o);
    $('#'+opts.formID.attr('id')).on('submit', function(e){
     e.preventDefault();
     $.ajax({
      form: opts.formID.attr('id'),
      url: opts.formID.attr('action'),
      type: opts.formID.attr('method'),
      data: opts.formID.serialize(),
      context: opts.context,
      cache: opts.cache,
      crossDomain: (opts.type==='jsonp') ? true : false,
      dataType: opts.type,
      beforeSend: function(xhr) {
       xhr.setRequestHeader('X-Alt-Referer', opts.appID);
       if (opt.formID.serialize()){
        xhr.setRequestHeader('X-Alt-Referer', pidCryptUtil.encodeBase64(pidCrypt.MD5($(this).serialize())));
       } else {
        xhr.setRequestHeader('X-Alt-Referer', pidCryptUtil.encodeBase64(pidCrypt.MD5(appID)));
       }
      },
      success: function(x){
       ((opts.callback)&&($.isFunction(opts.callback))) ?
         opts.callback.call(x) : console.log(x);
      },
      error: function(xhr, status, error){
       ((opts.errCallback)&&($.isFunction(opts.errCallback))) ?
         opts.errCallback.call(xhr, status, error) : console.log(xhr+status+error);
      }
     });
     return true;
    });
   }
  };
  if (methods[method]){
   return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
  } else if ((typeof method==='object')||(!method)){
   return methods.init.apply(this, arguments);
  } else {
   console.log('Method '+method+' does not exist');
  }
 };
})(jQuery);}

要使用插件,只需像这样创建一个 HTML 表单...

<form id="test" name="test" method="post" action="proxy.php">
 <label for="name">Name: <span class="required">*</span></label>
  <input type="text" id="name" name="name" value="" placeholder="John Doe" required="required" />
 <label for="email">Email Address: <span class="required">*</span></label>
  <input type="email" id="email" name="email" value="" placeholder="johndoe@example.com" required="required" />
 <label for="email">Confirm Email: <span class="required">*</span></label>
  <input type="email" id="email" name="email" value="" placeholder="johndoe@example.com" required="required" />
</form>

现在像这样将插件绑定到表单...

$('#test').AJAX();

此时,将 POST 数据发送到 proxy.php 脚本的工作客户端方法就位。这里的一个主要区别是,不仅仅是发送表单发布数据,一些自定义标头与 XMLHttpRequest 的表单数据一起发送。

现在在服务器上执行了几个简单的验证。首先检查以确保请求是 XMLHttpRequest,然后检查以确保 X-Alt-Referer 匹配,接下来将检查以确保在处理之前发布数据与相同的发布数据(序列化)哈希匹配。从技术上讲,它的工作原理很像校验和。

<?php
/* set the custom applicaiton string */
$appID = 'jQuery.AJAX'; // the plug-in URL https://github.com/jas-/jQuery.AJAX

/* verify an XMLHttpRequest was made */
if (strcmp($_SERVER['HTTP_X_REQUESTED_WITH'], 'XMLHttpRequest')!==0){
 exit('An XMLHttpRequest was not made');
}

/* verify associated X-ALT-Header value */
if (strcmp($_SERVER['HTTP_X_ALT_REFERER'], $appID)!==0){
 exit('The X-Alt-Referer information recieved is invalid');
}

/* verify associated Content-MD5 header value */
if (strcmp(base64_decode($_SERVER['HTTP_CONTENT_MD5']), md5(serialize($_POST)))!==0){
 exit('The Content-MD5 value is incorrect');
}
?>

是否有人有任何理由不使用这种类型的 POST 数据验证?提前致谢。

【问题讨论】:

    标签: header xmlhttprequest base64 md5


    【解决方案1】:

    您要防范什么? Content-MD5 标头是一种不错的解决方案,可以防止 TCP 校验和未捕获的传输错误,这种错误发生的频率比大多数人意识到的要多。对于主动修改数据的攻击者,它完全没有用,因为攻击者只需重新计算标头即可。

    不使用此标头的唯一原因是性能之一,客户端和服务器端都有开销(例如移动客户端)。您必须通过它为您提供的(小)保护来权衡成本。

    我发现这个blog entry 对此事很有帮助。

    【讨论】:

    • 我不确定我是否同意性能参数,因为一旦服务器将 JS 和 HTML 推送到客户端,就不会发生阻塞,并且库已经加载。
    • 它如何神奇地使校验和的计算变得即时和免费?
    • 您的权利。计算要附加到 content-md5 标头值的校验和有一些开销。
    猜你喜欢
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多