【发布时间】:2015-09-26 23:22:54
【问题描述】:
这个美丽的抽象让您可以将@Html.AntiForgeryToken() 放在 cshtml 文件中,该文件神奇地扩展为类似的东西;
<input name="__RequestVerificationToken" type="hidden" value="JjMHm5KJQ/qJsyC4sgifQWWX/WmADmNvEgHZXXuB07bWoL84DrmQzE6k9irVyFSJ5VSYqeUIXgl4Dw4NHSotLwflGYTyECzLvrgzbtonxJ9m3GVPgUV7Z6s2Ih/klUB78GN7Fl4Gj7kxg62MEoGcZw175eVwTmkKJ0XrtEfD5KCVvYIMHNY8MT2l+qhltsGL87c9dII42AVoUUQ2gTvfPg==" />
在提供页面之前通过 mvc。但是,我的页面有一些 JavaScript 进行 ajax 调用,这些调用不包含令牌,即使它已添加到表单中。他们目前正在获得预期的[HttpAntiForgeryException]: A required anti-forgery token was not supplied or was invalid.,因为他们没有令牌。我知道我可以从 DOM 中解析出值,但我不应该这样做。还有其他访问/获取此值的方法吗?明确地说,我的意思是我想要一个方法的重载,它只将值作为字符串或某种具有名称和值的对象返回。
为了提供更多上下文,我的表单和相关的 JS 看起来有点像这样;
<form action="/settings" method="post"><input name="__RequestVerificationToken" type="hidden" value="JjMHm5KJQ/qJsyC4sgifQWWX/WmADmNvEgHZXXuB07bWoL84DrmQzE6k9irVyFSJ5VSYqeUIXgl4Dw4NHSotLwflGYTyECzLvrgzbtonxJ9m3GVPgUV7Z6s2Ih/klUB78GN7Fl4Gj7kxg62MEoGcZw175eVwTmkKJ0XrtEfD5KCVvYIMHNY8MT2l+qhltsGL87c9dII42AVoUUQ2gTvfPg==" /> <fieldset>
<h3>User Settings</h3>
<ul>
<li>
label for="password">Password</label>
<a href="#" id="change_password" class="changePasswordButton">Edit</a>
<div id="password_section" class="inlineedit">
<div>
<span for="existing_password">Current password</span> <input autocomplete="off" class="required" id="existing_password" name="existing_password" type="password" />
</div>
<div>
<span for="new_password">New password</span> <input autocomplete="off" class="required" id="new_password" name="new_password" type="password" />
<span id="password_strength" />
</div>
<div>
<span for="confirm_password">Confirm password</span> <input autocomplete="off" class="required" id="confirm_password" name="confirm_password" type="password" />
</div>
<div class="inlinesave">
<input type="button" value="Change" onclick="onPostChangePassword();"/>
<a href="#" id="cancel_password" class="cancel">Cancel</a>
</div>
</div>
</li>
// a bunch more of these that call their own onPostChangeSetting method
onPostChangePassword() 然后进行一些输入验证;
if(validPWD && validNewPWD && validConfirmPWD && current_pwd != new_pwd){
// Post the password change
var currentAjaxRequest = $.ajax({
type: "POST",
url: "/settings/preferences/changepassword",
cache: false,
data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val()},
success: password_success,
error: password_error,
dataType: "json"
});
return true;
}
理想情况下(因为这是在 cshtml 文件中逐字记录的)会被这样修改;
data: {password: $('#new_password').val(), current: $('#existing_password').val(),confirm: $('#confirm_password').val(),
__RequestVerificationToken:@Html.AntiForgeryValue() }
tl;dr 有没有办法在 AntiForgeyToken 变成一串 html 之前与它进行交互?
【问题讨论】:
-
好奇:如果您要“解析”XHR 的其他数据(例如
password),为什么“您不必这样做”(对于令牌)?答案是否最终不得不(在 POST 请求中生成并发送它无论如何)? -
@EdSF by don't have to 我的意思是我应该能够将数据作为对象服务器端使用,所以我没有 JS 拦截 ajax 调用,从DOM,将其添加为标头,然后让执行继续。当页面被提供时,我应该能够像在 HTML 中一样将值嵌入到 ajax 调用中。可悲的是,您不能直接这样做,但这只是因为该库设计不佳。
-
仍然好奇 :) 基于此(以及下面的答案)似乎改变了事情的运作方式,我感到有点不安全:) 如果 我没看错,我可以重复使用该值(重播、模拟等)?
-
@EdSF 它可以防止重播。您可以在我的 cookie 或 DOM 中重放令牌的唯一方法是,如果您已经暴露了一个跨站点脚本漏洞,以便您解析我的 DOM 或读取我的 cookie。浏览器都不允许这些事情。
标签: c# .net asp.net-mvc asp.net-mvc-3 csrf