1. 程式人生 > >spring boot實戰之CSRF(跨站請求偽造)

spring boot實戰之CSRF(跨站請求偽造)

CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。攻擊通過在授權使用者訪問的頁面中包含連結或者指令碼的方式工作。例如:一個網站使用者Bob可能正在瀏覽聊天論壇,而同時另一個使用者Alice也在此論壇中,並且後者剛剛釋出了一個具有Bob銀行連結的圖片訊息。設想一下,Alice編寫了一個在Bob的銀行站點上進行取款的form提交的連結,並將此連結作為圖片src。如果Bob的銀行在cookie中儲存他的授權資訊,並且此cookie沒有過期,那麼當Bob的瀏覽器嘗試裝載圖片時將提交這個取款form和他的cookie,這樣在沒經Bob同意的情況下便授權了這次事務。

下面是CSRF的常見特性:
1. 依靠使用者標識危害網站
2. 利用網站對使用者標識的信任
3. 欺騙使用者的瀏覽器傳送HTTP請求給目標站點
4. 可以通過IMG標籤會觸發一個GET請求,可以利用它來實現CSRF攻擊

一個簡單的例子:
* 使用者小z登入了網站A,同時開啟網站B
* 網站B隱蔽的傳送一個請求至網站A
* 網站A通過session、cookie等身份標記判斷是使用者小z,執行對應操作

這樣網站B內的非法程式碼就盜用了使用者小z的身份,在小z不知情的情況下執行了攻擊者需要的操作,這就是跨站請求偽造。

防禦CSRF可以通過動態token驗證的方式來實現,每次請求生成一個動態token給前端,前端在後續的請求中附加該token,如果token不存在或不正確說明不是正常請求,予以遮蔽,從而達到解決CSRF問題的目的,以下是具體實現。

1、登入成功設定token

String uuidToken = UUID.randomUUID().toString();
map.put("token", uuidToken);
currentUser.getSession().setTimeout(NumberUtils.toLong(serverSessionTimeout, 1800)*1000);
request.getSession().setAttribute("token",uuidToken );
return map;

前後端分離架構,登入成功後將token傳遞給前端,由前端進行儲存。

2、建立CSRFFilter

/** 
 * CSRF跨域請求偽造攔截
 * 除登入以外的post方法,都需要攜帶token,如果token為空或token錯誤,則返回異常提示
 * 注意在filter初始化引數內配置排除的url
 * @author yangwk 
 */  
public class CsrfFilter implements Filter {  
    private static Logger logger = LoggerFactory.getLogger(CsrfFilter.class);

    public List<String> excludes = new ArrayList<String>();

    private boolean isOpen = false;//是否開啟該filter

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,ServletException {  
        if(!isOpen){
            filterChain.doFilter(request, response);
            return ;
        }
        if(logger.isDebugEnabled()){
            logger.debug("csrf filter is running");
        }

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        Object token = session.getAttribute("token");
        if(!"post".equalsIgnoreCase(req.getMethod()) || handleExcludeURL(req, resp) || token == null){
            filterChain.doFilter(request, response);
            return;
        }

        String requestToken = req.getParameter("token");
        if(StringUtils.isBlank(requestToken) || !requestToken.equals(token)){
            AjaxResponseWriter.write(req, resp, ServiceStatusEnum.ILLEGAL_TOKEN, "非法的token");
            return;
        }
        filterChain.doFilter(request, response);
    }

    private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
        if (excludes == null || excludes.isEmpty()) {
            return false;
        }
        String url = request.getServletPath();
        for (String pattern : excludes) {
            Pattern p = Pattern.compile("^" + pattern);
            Matcher m = p.matcher(url);
            if (m.find()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        if(logger.isDebugEnabled()){
            logger.debug("csrf filter init~~~~~~~~~~~~");
        }

        String temp = filterConfig.getInitParameter("excludes");
        if (temp != null) {
            String[] url = temp.split(",");
            for (int i = 0; url != null && i < url.length; i++) {
                excludes.add(url[i]);
            }
        }

        temp = filterConfig.getInitParameter("isOpen");
        if(StringUtils.isNotBlank(temp) && "true".equals(isOpen)){
            isOpen = true;
        }
    }

    @Override
    public void destroy() {}  

} 

除登入之外,post方式提交的請求都需要攜帶token,用於驗證。

3、註冊CSRFFilter

/**
 * csrf過濾攔截器
 */
@Bean
public FilterRegistrationBean csrfFilterRegistrationBean() {
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    filterRegistrationBean.setFilter(new CsrfFilter());
    filterRegistrationBean.setOrder(2);
    filterRegistrationBean.setEnabled(true);
    filterRegistrationBean.addUrlPatterns("/*");
    Map<String, String> initParameters = Maps.newHashMap();
    initParameters.put("excludes", "/login/*");
    initParameters.put("isOpen", isCsrfFilterOpen);
    filterRegistrationBean.setInitParameters(initParameters);
    return filterRegistrationBean;
}

小結

防禦CSRF攻擊可以通過在表單內新增隨機token來實現,本例內未提供token重新整理機制,可根據具體情況調整,如使用一次後重新整理或用舊的token獲取新的token等,不能提供一個重新整理介面,讓前端直接呼叫而不驗證舊有token,那樣該介面本身就是不安全的,會被偽使用者呼叫。
具體實現:
1. 登入成功,返回token給前端(前後端分離架構);
2. 建立CsrfFilter,對非登入的post請求,驗證其token是否正確;
3. 註冊CSRFFilter
4. 如有需要,可在token使用後重新整理或前端控制使用舊token換取新token。

相關推薦

spring boot實戰CSRF請求偽造

CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“One Click Attack”或者Session Riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。攻擊通過在授權使用者訪問的頁面中包含連結或者

CSRF請求偽造詳細說明

Cross-Site Request Forgery(CSRF),中文一般譯作跨站請求偽造。經常入選owasp漏洞列表Top10,在當前web漏洞排行中,與XSS和SQL注入並列前三。與前兩者相比,CSRF相對來說受到的關注要小很多,但是危害卻非常大。 通常情況下,有三

web安全2-- CSRF站點請求偽造

CSRF(Cross-site request forgery跨站請求偽造,也被稱成為“one click attack”或者session riding,通常縮寫為CSRF或者XSRF,是一種對網站的惡意利用。  一、CSRF攻擊原理 CSRF攻擊原理比較簡單,如圖1所示。其中W

ASP.NET MVC與CSRF腳本攻擊

轉移 off end gis 帳戶 blank 表單 密碼 message CSRF 一 何為CSRF CSRF(Cross-site request forgery跨站請求偽造,也被稱成為“one click attack”或者session riding,通常縮寫為CS

Django - CSRFCross-site request forgery 請求偽造

目錄 一、CSRF(Cross-site request forgery 跨站請求偽造) 1-1 CSRF 攻擊原理 1-3 CSRF 攻擊防範方式(主流的三種策略)  1-3-1 驗證HTTP Referer 欄位 1-3-2 在請求地址中新增token並驗證 1

你已經不再需要 CSRF站點請求偽造

本文作者:Scott Helme,安全研究員,國際演講者和本部落格的作者。也是 securityheaders.co

.NET Core實戰專案CMS 第十四章 開發篇-防止請求偽造XSRF/CSRF攻擊處理

通過 ASP.NET Core,開發者可輕鬆配置和管理其應用的安全性。 ASP.NET Core 中包含管理身份驗證、授權、資料保護、SSL 強制、應用機密、請求防偽保護及 CORS 管理等等安全方面的處理。 通過這些安全功能,可以生成安全可靠的 ASP.NET Core 應用。而我們這一章就來說道說道如何在

.NET Core實戰項目CMS 第十四章 開發篇-防止請求偽造XSRF/CSRF攻擊處理

部分 不錯 腳本註入 move 跟著 attribute 存在 serve 下一個 通過 ASP.NET Core,開發者可輕松配置和管理其應用的安全性。 ASP.NET Core 中包含管理身份驗證、授權、數據保護、SSL 強制、應用機密、請求防偽保護及 CORS 管理等

DVWA請求偽造CSRF

har 就會 之前 -s host 點擊 lang 不知道 string CSRF全稱是Cross site request forgery ,翻譯過來就是跨站請求偽造。 CSRF是指利用受害者尚未失效的身份認證信息(cookie,會話信息),誘騙其點擊惡意鏈接或者訪問包含

Spring security防止請求偽造CSRF防護

因為使用了spring security 安全性框架 所以spring security 會自動攔截站點所有狀態變化的請求(非GET,HEAD,OPTIONS和TRACE的請求),防止跨站請求偽造(CSRF防護),即防止其他網站或是程式POST等請求本站點。 如果是POS

Web安全測試請求偽造CSRF

 跨站請求偽造(即CSRF)被Web安全界稱為諸多漏洞中“沉睡的巨人”,其威脅程度由此“美譽”便可見一斑。本文將簡單介紹該漏洞,並詳細說明造成這種漏洞的原因所在,以及針對該漏洞的黑盒測試與灰盒子測試具體方法和示例,最後提提了一些防範該攻擊的建議,希望本文對讀者的安全測試

Python路67-防CSRF請求偽造

python目錄一、簡介二、應用三、官方示例一、簡介django為用戶實現防止跨站請求偽造的功能,通過中間件django.middleware.csrf.CsrfViewMiddleware來完成。而對於django中設置防跨站請求偽造功能有分為全局和局部。全局: 中間件 django.middlewa

Spring Boot實戰逐行釋義HelloWorld

runtime ica can pri source 訪問 exclude 這樣的 gradle 一、前言    研究Spring boot也有一小段時間了,最近會將研究東西整理一下給大家分享,大概會有10~20篇左右的博客,整個系列會以一個簡單的博客系統作為基礎,因為光

Spring Boot實戰數據庫操作

應該 element face 插入 sele run 方式 不同 pan   上篇文章中已經通過一個簡單的HelloWorld程序講解了Spring boot的基本原理和使用。本文主要講解如何通過spring boot來訪問數據庫,本文會演示三種方式來訪問數據庫,第一種是

Django框架 基於Ajax中csrf請求偽造

set lin cells ret body div nta java val ajax中csrf跨站請求偽造 方式一 1 2 3 $.ajaxSetup({ data: {csrfmiddlewaretoken: ‘{{ csrf_token

三十三、python學習Flask框架(五)模板:WTF表單、CSRF請求偽造、模板特有函式&變數

一、WTF表單: 1.web表單: Web 表單是 Web 應用程式的基本功能。預設開啟CSRF保護功能 它是HTML頁面中負責資料採集的部件。表單有三個部分組成:表單標籤、表單域、表單按鈕。表單允許使用者輸入資料,負責HTML頁面資料採集,通過表單將使用者輸入的資料提交給伺服器

請求偽造CSRF

跨站請求偽造(CSRF) 概念 CSRF,全稱為Cross-Site Request Forgery,跨站請求偽造,是一種網路攻擊方式,它可以在使用者毫不知情的情況下,以使用者的名義偽造請求傳送給被攻擊站點,從而在未授權的情況下進行許可權保護內的操作。 具體來講,可以這樣理解

Django框架十八—— 中介軟體、CSRF請求偽造

中介軟體 一、什麼是中介軟體 中介軟體是介於request與response處理之間的一道處理過程,相對比較輕量級,並且在全域性上改變django的輸入與輸出 二、中介軟體的作用 如果你想修改請求,例如被傳送到view中的HttpRequest物件。 或者你想修改view返回的HttpRespon

Django框架十八—— 中間件、CSRF請求偽造

exce meta messages options prot function port 信任 隨機 中間件 一、什麽是中間件 中間件是介於request與response處理之間的一道處理過程,相對比較輕量級,並且在全局上改變django的輸入與輸出 二、中間件的作用

django 淺談CSRFCross-site request forgery請求偽造 淺談CSRFCross-site request forgery請求偽造寫的非常好

淺談CSRF(Cross-site request forgery)跨站請求偽造(寫的非常好) 本文目錄 一 CSRF是什麼 二 CSRF攻擊原理 三 CSRF攻擊防範