My Quotes


When U were born , you cried and the world rejoiced
Live U'r life in such a way that when you go
THE WORLD SHOULD CRY






Wednesday, April 7, 2010

Output decoding using OWASP API

It was always on the back of my mind to centralize the output encoding using OWASP API rather than changing every single page in my application,.
Following two are the possible two options to implement for output encoding. However, our recommendation is to use Option 2.
Option 1: Implementing the solution in common place:
The encode implementation can be done in a response filter level. System has to pass all the responses through this filter, before rendering in front end.
This response filter should encode only the dynamic data which are rendered in the front end and not all the “JSP” file content.
Option 2: Implementing the encoding in all JSP files.
System has to encode all dynamic data which are in the “JSP” files using the below methods based on type of data.
value = escapeHtmlFull(value);
value = ESAPI.encoder().encodeForHTML(value);
value = ESAPI.encoder().encodeForHTMLAttribute(value);
value = ESAPI.encoder().encodeForJavaScript(value);
value = ESAPI.encoder().encodeForCSS(value);


In order to implement using the Session Filter here is my class which does the output decoding and centralizes the output decoding with OWASP API.

public final class MutableHttpResponse extends HttpServletResponseWrapper {

private ByteArrayOutputStream output = null;
private FilterServletOutputStream stream = null;
private PrintWriter writer = null;

public MutableHttpResponse(HttpServletResponse response) {

super(response);

reset();

}

public String getContent() throws IOException {
flushBuffer();

return new String(output.toByteArray());
}

public void setContent(byte[] content) throws IOException {
reset();
stream.write(content);
}

public void setContent(String s) throws IOException {

setContent(s.getBytes());
}

@Override

public void flushBuffer() throws IOException {
writer.flush();

stream.flush();

output.flush();

}

@Override

public ServletOutputStream getOutputStream() throws IOException {

return stream;

}
@Override
public ServletResponse getResponse() {
return super.getResponse();

}

@Override

public PrintWriter getWriter() throws IOException {

return writer;

}
@Override
public boolean isCommitted() {

return output.size() > 0;

}

@Override

public void reset() {

this.output = new ByteArrayOutputStream();
this.stream = new FilterServletOutputStream(output);

this.writer = new PrintWriter(stream);

}

@Override

public void resetBuffer() {

reset();

}

public void writeContent() throws IOException {

String content = getContent();
ServletResponse response = getResponse();
OutputStream os = response.getOutputStream();

response.setContentLength(content.length());

os.write(cleanXSS(content).getBytes());

os.close();

}

private String cleanXSS(String value) {

value = ESAPI.encoder().encodeForHTML(value);

value = ESAPI.encoder().encodeForHTMLAttribute(value);

value = ESAPI.encoder().encodeForJavaScript(value);

value = ESAPI.encoder().encodeForCSS(value);

return value;

}

}


The Session Filter code to invoke this MutableResponse is as follows
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// do your other stuff here
chain.doFilter(request, response);
MutableHttpResponse mutableResponse = new MutableHttpResponse(httpResponse);
mutableResponse.writeContent();
}



No comments :