跨站点请求伪造(CSRF)是一种攻击,它迫使最终用户在当前已通过身份验证的Web应用程序上执行不需要的操作。 如果您使用Spring Security 3.2及更高版本,在Spring MVC / Thymeleaf应用程序中防止CSRF攻击相当容易。
怎么测试?
为了进行测试,我创建了一个区域受限的应用程序,可以在其中发送表单。 表单的源代码:
<form class="form-narrow form-horizontal" method="post" th:action="@{/message}" th:object="${messageForm}" action="http://localhost:8080/message">
<fieldset>
<legend>Send a classified message</legend>
<div class="form-group" th:classappend="${#fields.hasErrors('payload')}? 'has-error'">
<label for="payload" class="col-lg-2 control-label">Payload</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="payload" placeholder="Payload" th:field="*{payload}" name="payload"/>
<span class="help-block" th:if="${#fields.hasErrors('payload')}" th:errors="*{payload}">May not be empty</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<button type="submit" class="btn btn-default">Send</button>
</div>
</div>
</fieldset>
</form>
知道操作URL是http:// localhost:8080 / message之后,我创建了一个单独的页面,其中包含一个引用该URL(带有所有参数)的HTTP请求:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<form action="http://localhost:8080/message" method="post">
<input type="hidden" name="payload" value="Hacked content!"/>
<input type="submit" value="Hack!" />
</form>
</body>
</html>
我登录了该应用程序并执行了上面的代码。 当然,服务器允许我执行请求,因为我的应用程序容易受到CSRF攻击。 要了解有关CSRF测试的更多信息,请访问此链接:
CSRF测试
。
如何保护?
如果您将XML配置与Spring Security一起使用,则必须启用CSRF保护:
<security:http auto-config="true" disable-url-rewriting="true" use-expressions="true">
<security:csrf />
<security:form-login login-page="/signin" authentication-failure-url="/signin?error=1"/>
<security:logout logout-url="/logout" />
<security:remember-me services-ref="rememberMeServices" key="remember-me-key"/>
<!-- Remaining configuration -->
</security:http>
如果是Java配置–默认情况下启用。
从Thymeleaf 2.1版本开始,CSRF令牌将自动添加到具有隐藏输入的表单中:
<form class="form-narrow form-horizontal" method="post" action="/message">
<!-- Fields -->
<input type="hidden" name="_csrf" value="16e9ae08-76b9-4530-b816-06819983d048" />
</form>
现在,当您尝试重复攻击时,将看到“
访问被拒绝”
错误。
但是要记住的一件事是,启用CSRF保护可确保注销需要CSRF令牌。 我使用JavaScript提交了隐藏表格:
<a href="/logout" th:href="@{#}" onclick="$('#form').submit();">Logout</a>
<form style="visibility: hidden" id="form" method="post" action="#" th:action="@{/logout}"></form>
摘要
在这篇简短的文章中,我展示了在使用Spring MVC(3.1 +),Thymeleaf(2.1+)和Spring Security(3.2+)时,如何轻松利用CSRF保护。 从Spring Security 4开始,使用XML配置时,默认情况下也会启用CSRF。 请注意,使用HTTP会话来存储CSRF令牌。 但这很容易改变。 有关更多详细信息,请参见参考。
-
我在
Spring MVC原型中
包含CSRF配置。 请检查!
资源资源