Cross-Site Request Forgery Vulnerabilities OWASP
Table of Contents
Cross-Site Request Forgery(CSRF) is one of the top 10 security vulnerabilities with high risk. It allows a hacker to perform an action on the vulnerable site on behalf of the victim(user). If the site does not validate the original request properly then the attack is possible.
Attacker forges the request with victim identity (session cookies, IP address etc..) and submits the request on his or her behalf. in other words, the site does not take the proper validation of user request to perform the specific action.
CSRF Solution
You need to implement CSRF token where the sensitive activity performing in the site. For example, save users, delete users, create users, etc…
Step 1: Generate CSRF Token
CSRF Token which is nothing but random unique string.To generate CSRF token you can use any strong algorithm
Step 2: Pass to JSP as a Hidden Parameter
Above generated token pass to JSP(frontend) as a hidden parameter and store the same token in the session object to validate while submitting the request in the below step.
Step 3: Validate the CSRF Token
Once the above step filled the form and submit the request, then validate the request CSRF token and session CSRF token. If both (request CSRF and session CSRF ) equal then allow the request to perform the activity else deny the request and redirect to the error page.
Example Code
The example code uploaded into a git repository and explained the required details
Generate Token
Here We are using commons-codec third party library to convert hash string to encode base64.
Pom.xml
<dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.14</version> </dependency>
public static String getHash() { String hash =""; try { String uuid=UUID.randomUUID().toString(); String secret = "SecretKey"; // String message = "Message"; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); hash = Base64.encodeBase64String(sha256_HMAC.doFinal(uuid.getBytes())); System.out.println(hash); } catch (Exception e){ System.out.println("Error"); } return hash; }
Send Token to Frontend
public static void setCSRFRequestData(HttpServletRequest request) { HttpSession session = request.getSession(); String hash = HMACSHA256.getHash(); request.setAttribute("csrf", hash); session.setAttribute("csrf", hash); }
Frontend
Add the below scriptlet code inside the form tag in the JSP where you have sensitive activity performing.
<% String csrf=""; if(null != request.getAttribute("csrf")){ csrf=request.getAttribute("csrf").toString(); } // out.print("csrf:"+csrf); %>
Validate The CSRF Token
At Controller
if (CSRFToken.getCSRFTokenStatus(request).equalsIgnoreCase("error")) { response.getWriter().println("<h1>invalid csrf token. <br>Invalid Request..</h1>"); } else { response.getWriter().println("<h1>Valid Request</h1>"); }
At Service
public static String getCSRFTokenStatus(HttpServletRequest request) { String error = "error"; String success = "success"; HttpSession session = request.getSession(); if (null == session.getAttribute("csrf") || null == request.getParameter("csrf")) { return error; } else { System.out.println("csrf from session:"+session.getAttribute("csrf")); System.out.println("csrf from request:"+request.getAttribute("csrf")); if (session.getAttribute("csrf").equals(request.getParameter("csrf"))) { System.out.println("csrf session and request are equal"); return success; } else { System.out.println("csrf session and request are not equal"); return error; } } }
Get full source code from GitHub
Hello! I am Narayanaswamy founder and admin of narayanatutorial.com. I have been working in the IT industry for more than 12 years. NarayanaTutorial is my web technologies blog. My specialties are Java / J2EE, Spring, Hibernate, Struts, Webservices, PHP, Oracle, MySQL, SQLServer, Web Hosting, Website Development, and IAM(ForgeRock) Specialist
I am a self-learner and passionate about training and writing. I am always trying my best to share my knowledge through my blog.