Skip to content

Commit

Permalink
SKF TSEC (#109)
Browse files Browse the repository at this point in the history
* SKF TSEC

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Update tsec_jsp_code_example_CSRF.md

* Rename skf/markdown/code_examples/java/TwelveSec/tsec_jsp_code_example_CSRF.md to skf/markdown/code_examples/code_snipet_jsp_antiCSRF.md

* Rename skf/markdown/code_examples/code_snipet_jsp_antiCSRF.md to skf/markdown/code_examples/java/TwelveSec/code_snipet_jsp_antiCSRF.md

* Title changed

* Title changed

* Code changed

* csrf

* csrf

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* csrf JSF implementation

* Update 1-code_example--CSRF_Token_JSF--.md

* Update 1-code_example--CSRF_Token_JSF--.md

* charsets

* charset

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* Update 12-code_example--file_upload--.md

* Update 12-code_example--file_upload--.md

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* code examples update

* Update 11-code_example--enforce_secure_passwords--.md

* Update 11-code_example--enforce_secure_passwords--.md

* Update 21-code_example--Password_forget_and_disallow_old_passwords--.md

* code examples update

* Update

* Update

* Update

* Update

* Update

* Delete ESAPI.properties

* Delete validation.properties

* xpath

* xpath

* xpath

* Delete 1-code_examples--jsp_CSRF_tokens--.md

* csrf code fixes

* csrf code fixes

* code fixes

* code fixes

* code fixes

* code fixes

* code example 26 changes

* code example 11 changes

* code example 26 changes

* code example 12 added jsp page that shows the path to destination

* changes at 10th snippet - encoding

* changes at 1st snippet - CSRF jsp

* changes at 11th snippet - password checking

* changes at snippet 11 - enforce passwords

* changes at snippet 12 - file upload

* changes at snippet 12 - file upload

* changes at snippet 31 - input Validation

* changes at snippet 30 - Session hijacking

* changes at snippet 21 - Password forget and password dissallow

* changes at snippet 18 - Login

* changes at snippet 6 - Audit Log

* changes at snippet 1 - CSRF Token Jsp

* changes at snippet 29 - Randomizer

* changes at snippet 29 - Randomizer

* changes at snippet 29 - Randomizer

* changes at snippet 29 - Randomizer

* general changes

* general changes

* changes at snippet 18 - Login

* changes in snippet 17 - identifier based authorization

* changes in snippet 8 - Rewrite

* changes in many snippets - inputValidation to InputValidation

* changes to java snippets - from randomizer to Randomizer

* changes to code snippet 40 - from xpath to XPath

* changes in code snippet 40 - from xpath to Xpath

* changes in code snippets - from hashing to Hashing

* changes in code snippets - from whitelisting to WhiteListing

* changes in code snippet 1 - CSRF Token

* remove TODO and stack traces

* substitution of e.printStackTrace() with logger.error (...)

* changes in snipet 11 and 31

* snippet changes

* snippet changes

* final changes

* final changes
  • Loading branch information
xen0vas authored and blabla1337 committed Jul 6, 2017
1 parent 641ca94 commit 10990c3
Show file tree
Hide file tree
Showing 43 changed files with 5,466 additions and 0 deletions.
111 changes: 111 additions & 0 deletions skf/markdown/code_examples/java/1-code_example--CSRF_Token--.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@


CSRF Token
-----------

***Example:***

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
For CSRF tokens we used a separate class outside of the normal controller, since
it must be re-used on several locations throughout the application
First after a successful validation of a user login, the application must also start a session
which contains the "cross site request forgery" token.
For generating the token we want to use a secure cryptographic function
SecureRandom random = new SecureRandom();
//Then we generate a long value token containing a high entropy
byte[] randomBytes = new byte[128];
random.nextBytes(randomBytes);
//Then we base64 encode the string
String csrftoken = Base64.getEncoder().encodeToString(randomBytes);
HttpSession session
session.setAttribute( "CSRF", csrftoken);
The next step is implementing this random token in each form field as a hidden input parameter
and send it to a function which checks if the submitted token is equal to the one set after succesful validation.
<%
Object token = request.getSession().getAttribute("CSRF");
String tokenStr = "";
if (token != null)
{
tokenStr = (String) token;
}
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Welcome to the OWASP CSRFGuard Test Application! Where would you like to go?
<br/>
<form action="/Home/csrf" method="post">
<input type="text" name="testValue" />
<br/>
<input type="hidden" value="<%=tokenStr%>" name="token"/>
<input type="submit" value="login">
</form>
*/
package com.edw;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/CheckCSRF")
public final class CheckCSRF extends HttpServlet
{
private static final long serialVersionUID = 1L;
public CheckCSRF() {
super();
}
//here we are sending the token towards the function which does the token validation
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String token = request.getParameter("token");
String sessionToken = (String) request.getSession().getAttribute("CSRF")
if(!sessionToken.equals(token))
{
/*
If there was no match, the authentication session will be emptied and sessions will be abandoned. Then, the user must be redirected towards the login page.
*/
if ("".equalsIgonereCase(request.getSession().getAttribute("authenticateUser")))
{
request.getSession().invalidate();
request.setAttribute("msg", "Served at: " + request.getContextPath());
RequestDispatcher rd = request.getRequestDispatcher("/login");
rd.forward(request, response);
return;
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.doGet(request, response);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
178 changes: 178 additions & 0 deletions skf/markdown/code_examples/java/1-code_example--CSRF_Token_JSF--.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
CSRF Tokens - JSF
-----------------


***Example:***


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/*
For CSRF tokens we used a separate class outside of the normal controller, since
it must be re-used on several locations throughout the application
After a successful validation of a user login, the application must also start a session
which contains the "cross site request forgery" token.
From the Randomizer class we are generating the token we want by using a secure cryptographic function
SecureRandom csprng = new SecureRandom();
Then we generate a long value token containing a high entropy
byte[] randomBytes = new byte[128];
prng.nextBytes(randombytes);
Then we base64 encode the string
String csrfToken = Base64.getEncoder().encodeToString(randomBytes);
Then we set the session attribute.
origRequest.getSession(false);
origRequest.getSession().setAttribute("CSRF", csrfToken);
The next step is to implement this random token in each form field as a hidden input parameter
and send it to a function which checks if the submitted token is equal to the one set after succesful validation.
The following .xhtml snippet shows the code used to place the antiCSRF token inside the page.
When the page renders, the <cu:antiCSRF/> is created as a viewstate encoded html input tag
which then carries the antiCSRF token.
While in process of rendering the page, a new token is generated
and added into the existing session.
When the user press the commandButton
then CSRF token parameter is compared with the CSRF session parameter.
*/
/*
<f:view contentType="text/html">
<f:event listener="#{userLoginView.isAuthenticated}" type="preRenderView" />
[ .... ]
<p:commandButton action="password?faces-redirect=true" value="Add User" ajax="false">
<cu:antiCSRF/>
</p:commandButton>
</h:form>
[ .... ]
/*
the following function used to generate the new Session which then is added to the already existing session.
*/
public void generateToken(){
HttpServletRequest origRequest = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
//we include the random password/token class.
Randomizer CSRF = new Randomizer();
/*
Now we create a random value for our CSRF tokens. See "Random password token generation" in
the code examples for more detailed information:
*/
String CSRftoken = CSRF.generate(25);
//Set an accesor session.
origRequest.getSession(false);
origRequest.getSession().setAttribute("CSRF", CSRftoken);
}
/*
the following function used to destroy the cookie and invalidate the session when the CSRF tokens dont match
*/
public void antiCSRF() throws IOException
{
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest origRequest = (HttpServletRequest)externalContext.getRequest();
HttpServletResponse origResponse = (HttpServletResponse)externalContext.getResponse();
String AUTH_KEY = (String) externalContext.getSessionMap().get("AUTH_KEY");
externalContext.getSessionMap().remove(AUTH_KEY);
externalContext.invalidateSession();
// Get an array of Cookies associated with this domain
Cookie[] cookies = origRequest.getCookies();
for (Cookie cookie : cookies)
{
if ("JSSESIONID".equalsIgnoreCase(cookie.getName()))
{
cookie.setValue(null);
origResponse.addCookie(cookie);
Log.SetLog("", "", "Cookie has been desroyed!", LocalDateTime.now(), "", "");
}
}
}
/*
This function used to decode the viewstate and get the token value from the html input tag. Also it perfomrms token comparison between the anticsrf token values of the html component and the session attribute. If the comparison fails then the session must be invalid.
*/
public void decode(FacesContext context) {
FacesContext fc = FacesContext.getCurrentInstance();
// access the hidden input field value
ExternalContext external = context.getExternalContext();
Map<?, ?> requestMap = external.getRequestParameterMap();
String value = String.valueOf(requestMap.get("_CSRFToken"));
// access the session and get the token
HttpSession session = (HttpSession) external.getSession(false);
String token = (String) session.getAttribute("CSRF");
// check if the token exists
if (value == null || "".equals(value)) {
try {
this.antiCSRF();
} catch (IOException e) {
logger.error(e.toString());
}
Log.SetLog("", "", "antiCSRF token doesnt match! Failed attempt", "", "NULL");
logger.info("antiCSRF token doesnt match! Failed attempt");
ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler) fc.getApplication().getNavigationHandler();
nav.performNavigation("csrf");
}
// check the values for equality
if (!value.equalsIgnoreCase(token)) {
try {
this.antiCSRF();
} catch (IOException e) {
logger.error(e.toString());
}
Log.SetLog("", "", "antiCSRF token doesnt match! Failed attempt", "", "NULL");
logger.info("antiCSRF token doesnt match! Failed attempt");
ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler) fc.getApplication().getNavigationHandler();
nav.performNavigation("UserLogin");
}
}
/*
the following function used to encode the viewstate with the html tag into a jsf component
*/
@Override public void encodeEnd(FacesContext context) throws IOException
{
//generate new token in every request
this.generateToken();
// get the session (don't create a new one!)
HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
// get the token from the session
String token = (String) session.getAttribute("CSRF");
// write the component HTML to the response
ResponseWriter responseWriter = context.getResponseWriter();
responseWriter.startElement("input", null);
responseWriter.writeAttribute("type", "hidden", null);
responseWriter.writeAttribute("name", "_CSRFToken", "");
responseWriter.writeAttribute("value", token, "CSRF");
responseWriter.endElement("input");
}
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 changes: 46 additions & 0 deletions skf/markdown/code_examples/java/10-code_example--encoder--.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

Encoder (SQL - ESAPI)
-----------

***Example:***

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package com.edw;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.codecs.MySQLCodec;
public final class Encoding {
AuditLog Log = new AuditLog();
public String encoder(String input , String allowed, String user_id)
{
/*
We can specify also special characters which allowed in order to keep
track of any unwanted special characters
Example :
To keep malicious inputs contained, any inputs written to the database need to be encoded.
SQL encoding: ' OR 1=1 --' is encoded to \' OR 1\=1 \-\-\'
*/
String pattern = "^[a-zA-Z0-9" + allowed + "]+$";
// Create a Pattern object
Pattern reg = Pattern.compile(pattern);
// Now create matcher object.
Matcher match = reg.matcher(input);
if (!match.find()) {
Log.SetLog(user_id, "Illegal characters", "FAIL", LocalDateTime.now(), "HIGH");
}
//We return the user input encoded
return ESAPI.encoder().encodeForSQL(new MySQLCodec(MySQLCodec.MYSQL_MODE), input);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Loading

0 comments on commit 10990c3

Please sign in to comment.