1. 程式人生 > >常見http請求漏洞問題

常見http請求漏洞問題

一 圖片防盜鏈

   圖片放盜鏈,就是說你上傳到伺服器端的網站的圖片,被別人呼叫了,以至於你的圖片的連結別人只要放在別人的網站上,也一樣可以通過你的網站的地址在別人的網站上展示這張圖片,那麼怎麼才能夠防止你的圖片不被其他人盜用呢。我們可以定義一個攔截器,進行請求路徑於域名的檢測。

 

1.1 配置過濾器

         <filter>

       <filter-name>ImgFilter</filter-name>

       <filter-class>com.itmayiedu.filter.ImgFilter</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>ImgFilter</filter-name>

       <url-pattern>/static/*</url-pattern>

    </filter-mapping>

1.2 攔截器程式碼

public class ImgFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

        System.out.println("初始化...");

    }


    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

            throws IOException, ServletException {

        System.out.println("doFilter....");

        HttpServletRequest req = (HttpServletRequest) request;

        HttpServletResponse res = (HttpServletResponse) response;

        //獲取請求頭中來源

        String referer = req.getHeader("referer");

        //獲取當前請求名稱

        String serverName = request.getServerName();

        System.out.println("referer:"+referer+"----serverName:"+serverName+":"+serverName);

        if(referer==null||(!referer.contains(serverName))){

        req.getRequestDispatcher("/imgs/error.png").forward(req, res);

        return ;

        }

        chain.doFilter(req, res);

    }


    public void destroy() {

    }

 

如上所示獲取請求頭中的referer是否是源於同一個域來作為圖片防盜鏈。

 

二 表單重複提交

1.1 原理

     表單重複提交,就是在提交表單的時候多次點選,看似提交了一次,實際已經做了多次提交的累加,還有就是提交以後,再次重新整理頁面的時候,又會產生一次提交,諸如此類的問題都屬於表單重複提交的問題,沒有解決請求的密等性問題。

 

如上圖所示要解決這個表單重複提交問題我可以,把之前從頁面到表單頁面的請求方式轉換一下變成先從後臺再到頁面。這個時候後臺生成一個token值。作為表單的影藏域,提交表單的時候,我們可以把token值也提交過去,可以通過對token值進行校驗。如果兩個token值相等的話,刪除後臺快取中的token。不相等的就可以判斷已經不是第一次進行提交了。

具體做法如下

1.2 案例

後臺

@WebServlet("/ForwardServlet")

public class ForwardServlet extends HttpServlet {

         @Override

         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

                   req.getSession().setAttribute("sesionToken", TokenUtils.getToken());

                   req.getRequestDispatcher("form.jsp").forward(req, resp);

         }

}

前臺頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"

         pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Form表單</title>


</head>


<body>

         <form action="${pageContext.request.contextPath}/DoFormServlet"

                   method="post" onsubmit="return dosubmit()">

                   <input type="hidden" name="token" value="${sesionToken}"> 使用者名稱:<input type="text"

                            name="userName"> <input type="submit" value="提交" id="submit">

         </form>

</body>

</html>

表單校驗


 

@WebServlet("/DoFormServlet")

public class DoFormServlet extends HttpServlet {

         @Override

         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

                   req.setCharacterEncoding("UTF-8");

                   boolean flag = isFlag(req);

                   if (!flag) {

                            resp.getWriter().write("已經提交...");

                            System.out.println("資料已經提交了..");

                            return;

                   }

                   String userName = req.getParameter("userName");

                   try {

                            Thread.sleep(300);

                   } catch (Exception e) {

                            // TODO: handle exception

                   }

                   System.out.println("往資料庫插入資料...." + userName);

                   resp.getWriter().write("success");

         }


         public boolean isFlag(HttpServletRequest request) {

                   HttpSession session = request.getSession();

                   String sesionToken = (String) session.getAttribute("sesionToken");

                   String token = request.getParameter("token");

                   if (!(token.equals(sesionToken))) {

                            return false;

                   }

                   session.removeAttribute("sesionToken");

                   return true;

         }

}

三 模擬請求

   也就是請求偽造,通過構造請求來瘋狂的請求網站,這個問題。也可以通過。表單重複提交的方式,來防止瘋狂的同源IP的攻擊。只要是同一個IP它每請求一次都會衝後臺生成一個token它都要做一次切換。這樣就有效的避免了模擬請求。所有的內部暴露介面。為了防止使用者不斷的請求都可以通過

https://cx.com?sign=xxx&code=md5(xxx);

可以使用類似md5的自己構建的演算法,通過隨機生成的引數sign進行隨機校驗。這樣就可以保證內部暴露介面不被外部瘋狂的請求。至於向外暴露的介面,每一個源IP若非特殊設計,可以限制它在一定時間的的請求次數。選擇拒絕。

四 跨域

1 通過jsonp,只能解決get跨域問題

2 通過httpclient進行內部轉發

3 通過nginx代理伺服器,轉向正確的玉面

4 通過springcloud相關知識的zuul閘道器機制進行處理