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();
}
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
Powered by Find-IP.net
Wednesday, April 7, 2010
Subscribe to:
Post Comments
(
Atom
)
No comments :