Jquery .Net MVC-Can';不要阻止我的Ajax.begin被黑客攻击
我已经在我的.NETMVCWeb应用程序中构建了一个基于Ajax的表单,但我无法阻止被黑客攻击并被用来向我发送垃圾邮件Jquery .Net MVC-Can';不要阻止我的Ajax.begin被黑客攻击,jquery,ajax,asp.net-mvc,forms,Jquery,Ajax,Asp.net Mvc,Forms,我已经在我的.NETMVCWeb应用程序中构建了一个基于Ajax的表单,但我无法阻止被黑客攻击并被用来向我发送垃圾邮件 @using (Ajax.BeginForm("ContactSend", "Home", null, new AjaxOptions { OnBegin = "Contact.submitOnBegin", OnSuccess = "Contact.submitOnSuccess" }, new
@using (Ajax.BeginForm("ContactSend", "Home", null, new AjaxOptions { OnBegin = "Contact.submitOnBegin", OnSuccess = "Contact.submitOnSuccess" }, new { id = "contact-form" }))
{
@Html.AntiForgeryToken()
<input id="contact-cta" type="hidden" name="cta" value="@ViewBag.CTA" />
<label class="form-label" for="nome">@Resources.Contact_Form_Name <span class="mandatory">*</span></label>
<div class="form-input-ctn">
<input id="contact-name" type="text" name="name">
<div class="mandatory-error">@Resources.Contact_Form_Mandatory</div>
</div>
<label class="form-label" for="email">@Resources.Contact_Form_Email <span class="mandatory">*</span></label>
<div class="form-input-ctn">
<input id="contact-email" type="text" name="email">
<div class="mandatory-error">@Resources.Contact_Form_Mandatory</div>
<div class="invalid-error">@Resources.Contact_Form_Invalid</div>
</div>
<label class="form-label" for="phone">@Resources.Contact_Form_Phone <span class="mandatory">*</span></label>
<div class="form-input-ctn">
<input id="contact-phone" type="text" name="phone">
<div class="mandatory-error">@Resources.Contact_Form_Mandatory</div>
<div class="invalid-error">@Resources.Contact_Form_Invalid</div>
</div>
if (!string.IsNullOrEmpty(ViewBag.Subject))
{
<label class="form-label" for="subject">@Resources.Contact_Form_Subject</label>
<div class="form-input-ctn">
<input id="contact-subject" type="text" name="subject" value="@ViewBag.Subject">
<div class="mandatory-error">@Resources.Contact_Form_Mandatory</div>
</div>
}
<label class="form-label" for="message">@Resources.Contact_Form_Message <span class="mandatory">*</span></label>
<div class="form-input-ctn">
<textarea id="contact-message" class="form-textarea" name="message">@ViewBag.Message</textarea>
<div class="mandatory-error message-mandatory-error">@Resources.Contact_Form_Mandatory</div>
</div>
<label class="form-label"><span class="mandatory">*</span> @Resources.Contact_Form_Mandatory</label>
<div class="form-input-ctn">
<div id="contact-recaptcha-mandatory-error" class="recaptcha-mandatory">@Resources.Contact_Form_Mandatory</div>
<div id="contact-recaptcha" class="g-recaptcha" data-callback="reCaptchaOnValidCallback"></div>
</div>
<br />
<input id="contact-submit-btn" class="form-submit" type="submit" value="@Resources.Contact_Form_Send_Button" data-sending-message="@Resources.Contact_Form_Sending_Button">
}
在isFormValid函数中,我对每个输入执行所有测试:
var _isFormValid = function () {
// Reset
isFocusOn = false;
isFormValid = true;
// Name
if ($contactName.val() == "") {
_showErrorMessage($contactName, contactErrorMandatoryCls);
}
// Email
if ($contactEmail.val() == "") {
_showErrorMessage($contactEmail, contactErrorMandatoryCls);
}
else if (!_isEmailValid()) {
_showErrorMessage($contactEmail, contactErrorInvalidCls);
}
// Phone
if ($contactPhone.val() == "") {
_showErrorMessage($contactPhone, contactErrorMandatoryCls);
}
else if (!_isPhoneValid()) {
_showErrorMessage($contactPhone, contactErrorInvalidCls);
}
// Message
if ($contactMessage.val() == "") {
_showErrorMessage($contactMessage, contactErrorMandatoryCls);
}
// reCaptcha
var reCaptchaResponse = grecaptcha.getResponse();
if (reCaptchaResponse.length == 0) {
isFormValid = false;
$("#contact-recaptcha-mandatory-error").addClass(contactErrorRecaptchaMandatoryCls);
}
};
var _reCaptchaRender = function () {
grecaptcha.render('contact-recaptcha', {
'sitekey': 'XXX'
});
};
var _reCaptchaValid = function () {
$contactRecaptchaMandatoryError.removeClass(contactErrorRecaptchaMandatoryCls);
};
var _showErrorMessage = function (el, msg) {
el.addClass(contactErrorMandatoryCls);
el.parent().find("." + msg).fadeIn();
if (!isFocusOn) {
el.focus();
isFocusOn = true;
}
isFormValid = false;
};
更奇怪的是,他们能够用reCaptcha对表单进行黑客攻击,还可以发送主题中的空值
在Contact.SubmitOnSuccess中,如果一切正常,我将进行提交:
var _submitOnSuccess = function (ajaxResult) {
sentResultOk = ajaxResult.Success;
$sentModal.load("/home/contactsent?cta=" + $contactCTA.val(), function () {
if (sentResultOk == true) {
$("#" + sentModalOkId).show();
}
else {
$("#" + sentModalErrorId).show();
}
$sentModal.fadeIn(function () {
$contactForm[0].reset();
grecaptcha.reset();
$submitBtn.removeClass("submitting");
$submitBtn.prop('disabled', false);
$submitBtn.val("Enviar");
});
});
我无法停止被黑客攻击,并被用来向我发送垃圾邮件
问题的核心反映在对该问题的评论中:
该表单在有效之前不会进入服务器端,从我在谷歌文档中看到的文档来看,我确信我只能从客户端进行验证
发生的情况是,您依赖于客户端告诉服务器一切都是有效的。所以任何黑客都可以。。。告诉服务器一切都是有效的
永远不要含蓄地相信来自客户的东西。始终验证
对于reCaptcha,Google会返回带有令牌的客户端代码,而您会这样做。请记住,此令牌的验证是在与处理表单相同的服务器端操作中完成的。毕竟,如果您首先让客户端将令牌发送到服务器并获得有效/无效响应,然后将表单发送到服务器,那么您就回到了与以前相同的位置。。。客户端只需将表单发送到服务器并声明它是有效的
在不深入示例的情况下,总体流程应该是:
任何失败的步骤,你都会以你认为合适的方式处理这个错误。在大多数情况下,您只需返回一些错误响应给客户端,或者重定向到错误页面,或者返回AJAX错误并在客户端代码中优雅地处理它。您不需要假设任何错误都是由于黑客企图造成的。只是显示一个友好的错误,仅此而已。只要攻击者无法获得进一步的信息,错误说明对他们来说并不重要。在服务器端代码中,在哪里验证reCaptcha结果?我在这里只看到客户端代码。如果你依赖客户端告诉你它是否有效,那么这就解释了为什么它被黑客攻击。黑客只是告诉你它是有效的。你必须验证他们是否真的解决了验证码,而不仅仅是告诉你他们解决了验证码。客户端不需要执行JavaScript,甚至不需要在web浏览器中与之交互。他们可以向您的服务器发送他们喜欢的任何请求。验证该请求取决于服务器端代码。永远不要信任来自客户端的任何东西。基本上,当用户将表单提交到服务器时,该表单应该包含reCaptcha响应令牌。在服务器端代码中,您将验证表单(如果无效,则返回一个错误),然后使用Google验证令牌(如果无效,则返回一个错误),然后如果所有内容都有效,则处理表单。可能,也可能不是。如何处理任何给定的错误取决于您。也许客户端验证有一个bug,也许reCaptcha暂时存在连接问题,等等。您不需要假设用户正在做一些恶意的事情,只要适当地处理验证即可。因此,如果他们没有做恶意的事情,他们会看到一个有用的错误。如果他们做了一些恶意的事情,他们所看到的只是一个有用的错误。非常感谢@David!
var _submitOnSuccess = function (ajaxResult) {
sentResultOk = ajaxResult.Success;
$sentModal.load("/home/contactsent?cta=" + $contactCTA.val(), function () {
if (sentResultOk == true) {
$("#" + sentModalOkId).show();
}
else {
$("#" + sentModalErrorId).show();
}
$sentModal.fadeIn(function () {
$contactForm[0].reset();
grecaptcha.reset();
$submitBtn.removeClass("submitting");
$submitBtn.prop('disabled', false);
$submitBtn.val("Enviar");
});
});