2016-06-09 6 views
2

Я пытаюсь предотвратить мой веб-приложение от CSRF (запрос Cross сайта подлога) Я следовал этой ссылке Link for CSRFКак предотвратить мой веб-приложение от CSRF (запрос Cross сайта подлога) в Java

Это то, что у меня есть пытался. Чтобы реализовать этот механизм в Java, я решил использовать два фильтра: один для создания соли для каждого запроса, а другой - для проверки его. Поскольку запросы пользователей и последующие POST или GET, которые должны быть проверены, не обязательно выполняются в порядке, я решил использовать кеш тайм-аута для хранения списка действительных солевых строк.

Первый фильтр, используемый для создания новой соли для запроса и хранить его в кэше может быть закодирован следующим образом:

public class LoadSalt implements Filter{ 


    public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException { 

     // Assume its HTTP 
     HttpServletRequest httpReq = (HttpServletRequest)request; 
     // Check the user session for the salt cache, if none is present we create one 
     @SuppressWarnings("unchecked") 
     Cache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>) 
       httpReq.getSession().getAttribute("csrfPreventionSaltCache"); 

     System.out.println("Checking cahce befor creating it from Request :csrfPreventionSaltCache: "+csrfPreventionSaltCache); 

     if(csrfPreventionSaltCache == null) 
     { 
      System.out.println("csrfPreventionSaltCache is null have to create new one"); 
      String csrfPreventionfromrequest = (String) httpReq.getSession().getAttribute("csrfPreventionSaltCache"); 
      System.out.println("csrfPreventionfromrequest :"+csrfPreventionfromrequest); 

      // creating a new cache 
      csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000) 
        .expireAfterAccess(20, TimeUnit.MINUTES).build(); 

      // Setting to gttpReq 
      httpReq.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache); 

      System.out.println("After setting the csrfPreventionSaltCache to HttpReq"); 
      System.out.println("--------csrfPreventionSaltCache------ :"+httpReq.getSession().getAttribute("csrfPreventionSaltCache")); 
     } 



     // Generate the salt and store it in the users cache 
     String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom()); 
     System.out.println("Salt: "+salt); 
     csrfPreventionSaltCache.put(salt, Boolean.TRUE); 
     // Add the salt to the current request so it can be used 
     // by the page rendered in this request 
     httpReq.setAttribute("csrfPreventionSalt", salt); 

     System.out.println("Before going to validate salt checking for salt in request"); 
     System.out.println(" httpReq.getAttribute(csrfPreventionSalt) ----:"+httpReq.getAttribute("csrfPreventionSalt")); 
     // System.out.println(" httpReq.getSession().getAttribute(csrfPreventionSalt) :----"+httpReq.getSession().getAttribute("csrfPreventionSalt")); 


     chain.doFilter(request, response); 
    } 
    public void init(FilterConfig arg0) throws ServletException { 

    } 

    public void destroy() { 

    } 
} 

Mapping в web.xml

 <filter> 
      <filter-name>loadSalt</filter-name> 
      <filter-class>com.globalss.dnb.monitor.security.LoadSalt</filter-class> 
     </filter> 

     <filter-mapping> 
      <filter-name>loadSalt</filter-name> 
      <url-pattern>/*</url-pattern> 
     </filter-mapping> 

для проверки соли перед выполнением безопасных транзакций я написал еще один фильтр:

Mapping для второго Filetr в web.xml

<filter> 
      <filter-name>validateSalt</filter-name> 
      <filter-class>com.globalss.dnb.monitor.security.ValidateSalt</filter-class> 
     </filter> 

     <filter-mapping> 
      <filter-name>validateSalt</filter-name> 
      <url-pattern>/*</url-pattern> 
     </filter-mapping> 

После настройки как сервлеты все ваши запросы обеспеченных wasfailing :). Чтобы исправить это, я должен был добавить к каждой ссылке и сообщению формы, которая заканчивается защищенным URL, параметр csrfPreventionSalt, содержащий значение параметра запроса с тем же именем. Например, в HTML форме внутри страницы JSP:

<form action="/transferMoneyServlet" method="get"> 
    <input type="hidden" name="csrfPreventionSalt" value="<c:out value='${csrfPreventionSalt}'/>"/> 
    ... 
</form> 

После всего этого я стараюсь, чтобы попытаться CSRF, Это то, что я сделал

<html> 
 
<body> 
 
<form action="http://localhost:8080/mywebapp/dispatcherServlet/addUserController/addUser" method="POST" enctype="text/plain"> 
 
<input type="hidden" name="&#123;&quot;userName&quot;&#58;&quot;CSRUser&quot;&#44;&quot;password&quot;&#58;&quot;CSRFUser123&quot;&#44;&quot;roles&quot;&#58;&quot;true&quot;&#44;&quot;status&quot;&#58;&quot;true&quot;&#125;" value="" /> 
 
<input type="submit" value="Submit request" /> 
 
</form> 
 
</body> 
 
</html>

Когда я ударил отправьте запрос, я получил ответ «Успех», и CSRUser был добавлен в мою базу данных.

Я что-то упускаю, как предотвратить атаку CSRF?

+0

Полезно! Это помогает мне –

ответ

1

Вы можете использовать Spring Security для аутентификации пользователей и авторизации. Поддержка Cross Site Request Forgery (CSRF) по умолчанию начинается с версии Spring 3.2.0.

Вы также можете легко исключить эти URL-адреса вы не хотите, чтобы защитить с помощью RequestMatcher:

public class CsrfSecurityRequestMatcher implements RequestMatcher { 
private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$"); 
private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("/unprotected", null); 

@Override 
public boolean matches(HttpServletRequest request) { 
    if(allowedMethods.matcher(request.getMethod()).matches()){ 
     return false; 
    } 

    return !unprotectedMatcher.matches(request); 
} 
} 

Source

+0

Я использую сервлет 2.5 и весну 3, действительно ли весна 3.0 обеспечивает поддержку CSRF – Varun

+1

Нет, Spring Security обеспечивает поддержку CSRF, начиная с версии 3.2.0. https://spring.io/blog/2013/08/21/spring-security-3-2-0-rc1-highlights-csrf-protection/ –

0

У меня были те же вопросы, несколько дней назад, и я нашел тот же самый статья.

На самом деле, когда я скопировать и вставить его, я думал о том, как обеспечить это было ...

Итак, моя первая мысль была, чтобы действительно получить в поисках, чтобы понять, что CSRF атак: OWASP - Cross Site Request Forgery.

После того, как я понял, первое, что я сделал, это взломать мое приложение с помощью HTTP GET и POST, и я был действительно удивлен, насколько это было легко: Here еще немного объяснений о CSRF и о том, как это сделать).

Наконец, я понимаю, «есть больше CSRF атак, чем встречает глаз» и определенно, эта статья не гарантирует безопасность на всех, так как нет никакого объяснения о лексемах инъекции и таким образом, вы не можете заверить злоумышленник не имеет действительного токена. В этом случае токен фильтрации бесполезен.

В этом пункте я рекомендую прочитать больше в OWASP CSRF Prevention Cheat Sheet, чтобы углубиться в него.

И последнее, но не менее важное: в моем случае я решил использовать de OWASP CSRF Guard library, который очень настраиваемый/гибкий и с открытым исходным кодом. Итак, в конце концов, если вы решите не идти с этим, по крайней мере, у вас будет лучшее представление о том, как реализовать его самостоятельно, следуя некоторой его архитектуре.

[обновление]

Ну, unfortunally я не мог идти с CSRF Guard либо, из-за следующих недостатков:

  1. Он основан на запросе синхронного АЯКС, который в процесс удаления с веб-платформы: https://xhr.spec.whatwg.org/

  2. Я не мог заставить его работать с генерацией динамической формы, потому что невозможно получить доступ к токену, чтобы добавить ах скрытое поле в динамической форме. Я думаю, что по дизайну, но я не мог изменить свое приложение, чтобы адаптироваться к этой реальности;

  3. Я не мог заставить его работать с многочастными формами;

К счастью, я пересекла очень хороший ответ here, который направляет меня, чтобы сделать свою собственную реализацию с помощью «Set-Cookie» стратегию.

Надеюсь, это поможет.