我们正尝试使用CSRFGuard为现有的Java Web应用程序添加CSRF保护。我们已经关注了OWASP的guide to token injection,这让我们大部分都在那里。我们正在使用动态DOM操作方法,并发现大多数URLS /表单/ AJAX调用都使用插入的CSRF令牌进行了正确格式化。我们的问题是:
某些页面的某些部分是由返回jspfs的AJAX调用动态生成的。返回的jspfs具有从不受CSRFGuard DOM操作约束的链接,因此没有CSRF令牌。单击这些链接会导致CSRF违规,因为没有令牌。
此外,根据OWASP guide for AJAX support,动态脚本需要在AJAX调用之前引用,以便拦截AJAX调用并将CSRF令牌插入到头中。这是动态更新DOM的相同脚本。所以 - 为了解决这个问题中提出的问题,我需要在 AJAX调用之后运行脚本,但我还需要在 AJAX调用之前运行它来实现它首先。试图运行两次会导致问题。
这里适当的解决方案是什么?是否需要修改CSRFGuard javascript文件,以便针对目标元素运行动态令牌注入?这个问题已经解决了吗?
答案 0 :(得分:1)
我遇到了同样的问题。我用这种方式修改了csrfguard.js:
我定义了2个新功能
function getTokenNameValuePair() {
var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
var csrfToken = {};
xhr.open("POST", "%SERVLET_PATH%", false);
xhr.setRequestHeader("FETCH-CSRF-TOKEN", "1");
xhr.send(null);
return xhr.responseText;
}
function injectTokensForNewTags() {
var token_pair = getTokenNameValuePair();
token_pair = token_pair.split(":");
var token_name = token_pair[0];
var token_value = token_pair[1];
injectTokens(token_name, token_value);
}
返回带有链接的HTML块的AJAX应如下所示:
$.post(loadurl, function(data) {
$(target).html(data);
injectTokensForNewTags();
});
答案 1 :(得分:0)
注意:此答案需要修改CSRFGuard。
我正在使用SkateJS(https://github.com/skatejs/skatejs)来监听< a>,< img>和< form>的动态更新标记并调用我添加到csrfguard.js的例程,以将标记添加到它们。
这捕获了javascript工具包在初始DOM加载后插入的标记。
我还必须修改脚本,以防止它在加载时始终扫描整个DOM树以插入令牌。这是非常低效的,并且不需要上述方法。
以下是SkateJS配置的示例:
window.addEventListener('load',
function() {
var config = {
ready : function(element) {
if (CsrfGuard && CsrfGuard.isEnabled) {
CsrfGuard.injectTokens([element]);
} else {
skate.destroy();
}
},
type : skate.types.TAG
};
skate('a', config);
skate('img', config);
skate('form', config);
}
);
注意:这不适用于IE8。为此,我正在使用Microsoft DHTML行为。
<![if IE 8]>
<style>
a,img,form {
behavior: url("csrf_ie8.htc");
}
</style>
<![endif]>
csrf_ie8.htc:
<public:attach event="ondocumentready" onevent="CsrfGuard.injectTokens([element]);" />