I'm looking for an alternative to PHP's htmlspecialchars() or even better, for a global solution using Spring MVC. For example, it would be great if data passed from Controller to View using ModelAndView or ModelMap was automatically processed so I could be sure that I'm working with safe strings inside jsp View.
If you're using JSPs to display your data, all you need to do is use the JSTL's <c:out> tag, or fn:escapeXml() function to escame the HTML special chars:
Last Name : <c:out value="${someBean.lastName}"/>
First Name : ${fn:escapeXml(someBean.firstName)}
I would definitely not do this in the controller. This is one of the view's jobs.
Related
How can we implement ESAPI output encoding in an application using java and spring-mvc.
Read many posts and saw this:
<%# page import="org.owasp.esapi.*" %>
<input type="hidden" name="hidden" value="<%out.print(ESAPI.encoder().encodeForHTML(content));%>"/>
But, in my application all the jsps use spring form tags like the following,
<td>Number:
<form:input path="someNo" size="20" maxlength="18" id="firstfield" onkeypress="return PressAButton('submithidden');"/></td>
How can I have ESAPI implementation for above code? is there any other way of implementing output encoding like creating a filter or something? Any suggestions are greatly appreciated!
After researching spring tags a bit, it appears that the data-binding happens in framework code thus preventing you from applying any escaping in the jsp.
One, semi-quick win could be defaulting all output to escape HTML. Add this entry in web.xml:
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
The only problem here is that output-escaping is a BIG pain... the rules for html escaping are different when your value is going to be passed as data to an HTML attribute or a Javascript function. And there could be some parts of your application where you DO NOT want to html escape, but you should be able to override those with the form tag attribute htmlEscape="false" when you need to.
What you need is to be able to hook the part of Spring tags where it is binding the HTML to the form, but you need to be able to do it so you can escape based on where its being placed. Escaping rules are different for an HTMLAttribute as opposed to plain HTML and if the value is going to be passed as data to a javascript function. So Spring's solution only defends one category of attack.
These are the only ways out I see, all of them will require work:
Use JSTL tags instead of Spring tags so you can write your variables with ${thisSyntax} and wrap them in esapi tags like this:
<c:out value="<esapi:encodeForHTML>${variable}</esapi:encodeForHTML>"/>
Follow a solution like what #A. Paul put forward, where you do your context escaping back on the controller side. I'm aware you feel that this isn't an option, but the next solution I'm putting forward is untested.
Implement your own tag library that subclasses [org.springframework.web.servlet.tags.form.InputTag][1], specifically the method writeValue. While esapi prevents alot, I would recommend looking at owasp's new Encoder project to show you exactly how tricky output encoding is. Ideally your tag library will allow you to utilize either esapi's Encoder or this new API.
Just a thought not sure if this is what you are looking for.
Can you use the below code in Java and change the data in the bean itself and then send in the user interface.
if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) {
data = ESAPI.encoder().encodeForHTML(message);
}
You can check the below url.
http://www.jtmelton.com/tag/esapi/
I am trying to implement this use case in a RESTful manner in my Spring MVC application. Imagine having a POJO called SalesReport with a list of Sales. Using content negotiation I'm able to return the XML and JSON representations. For example...
<SalesReport>
<Sale>...</Sale>
</SalesReport>
For my HTML representation it needs to be sexier, of course. The requirement is to display a chart using Highcharts as well as the data in table format. Pretty standard stuff. I am unsure of how to accomplish this in an elegant way. I thought about
Serializing SalesReport to an XML/JSON formatted String and doing request.setAttribute(). I feel like this couples my controller with my view. My XML and JSON representations don't need this.
Making an AJAX call to get the data after the JSP loads. This seems wasteful to make another HTTP request and my data is not cached either.
Create util class with functions that uses Spring MVC's JSON and XML libs to return the serialized format I need. Then in the JSP do something like <%= RestUtil.toJSON(salesReport) %>. This way my controller doesn't know specifics about my HTML view and I'm not sending extra HTTP calls.
What is a good approach to this?
Why would you use JSON/XML in the JSP? Using content-negotiation text/html should correspond with a controller method. You can access the POJO directly with the spring-form tld or JSTL in the jsp.
Assuming you have the view resolver set up:
#RequestMapping("salesreport")
public String getSalesReport(ModelMap model) {
model.addAttribute("reports", salesReportService.findAll());
return "reports/view";
}
In reports/view.jsp:
<c:forEach items="reports" var="report">
Field 1: ${report.field1} <br/>
Field 2: ${report.field2}
</c:forEach>
I'm using spring to display a jsp page. That's fine. Now I'd like to include another page in it. I know I can use the <jsp:include> tag in my page however I'd like to use a controller to pass some logic to the page which is to be included. Is it possible please?
Thanks,
Krt_Malta
You might want to checkout a template engine like Freemarker or Velocity. Here's a description of how Spring integrates with view technologies.
Your controller can add objects to the Model and Spring will add them to the HTTPRequest as attributes, is that what you mean? Including a jsp fragment doesn't affect that, your jsp fragment can access the request attributes. Otherwise it's unclear to me what you mean by "passing some logic to the page".
Look into JSTL (Jsp Standard Tag Library).
You can implement conditional logic in your JSP using the JSTL <c:if> or <c:choose> tags. Then, instead of splitting up the logic into multiple files and using <jsp:include> to include the logic you want, you can build all the logic into your page and the controller can set request (or other scope) attributes to turn on the logic you desire.
For example:
<c:if test="${Order66}"
<c:forEach items="${JediMembership}" var="jedi">
kill ${jedi}
</c:forEach>
</c:if>
<c:if test="${Order67}"
two large pizza, extra cheese.
</c:if>
The controller then set "Order66" and / or "Order67" in the request (or any other scope).
I am using Servlet and JSP without a framework to study for my SCWCD. I have a simple form that I want the parameters to bind to a bean automatically. Is this possible without writing binding code or using a framework?
Thanks
Well, without a "framework" you can't do this. But you can use the Jakarta BeanUtils (http://commons.apache.org/beanutils/), more precisely the static method BeanUtils.populate in your servlet. Ex.:
BeanUtils.populate (myBean, request.getParameterMap());
Remember: the input properties names must match with bean attributes, ok?
You can do this with <jsp:useBean>.
<jsp:useBean id="form" class="com.example.Form" scope="request" />
<jsp:setProperty name="form" property="*" />
<jsp:include page="servletUrl" />
All bean properties whose names match the request parameter names -if any- will be set and the bean will be available as request attribute in the servlet matching the url-pattern of /servletUrl.
However, you'd like to use a servlet and/or MVC framework for this since it abstracts it all away and gives a better control over actions and response handling. This is essentially abuse of JSP (as being a view technology) as controller (which should be (in)directly done by a Servlet).
No, it isn't. You should use some framework, which I guess would be an overkill.
So what you can do, is iterate request.getParameterMap() keys and set the values to object with the corresponding field names (via reflection)
Is it possible to have a servlet that contains an object (an ArrayList in this case) that then does the equivalent of displaying a jsp page and passing that object to the jsp page. In this case the ArrayList contains database results an I want to iterate through and display the results on the JSP page.
I am not using any MVC framework, is it possible to do this with the basic Servlet/JSP architecture.
Yes.
in the servlet call request.setAttribute("result", yourArrayList);
then forward to the jsp:
getServletContext().getRequestDispatcher("your.jsp")
.forward(request, response);
using JSTL, in the jsp:
<c:forEach items="${result}" var="item">
...
</c:forEach>
If you don't want to use JSTL (but I recommend using it), then you can get the value using request.getAttribute("result") in the JSP as well.
Alternatively, but not recommended, you can use request.getSession().setAttribute(..) instead, if you want to redirect() rather than forward().
You can pass objects to jsp's by embedding them within the Request.
request.setAttribute("object", object);
and within the jsp:
request.getAttribute("object");
You can put it using request.setAttribute("myobj", myObj); see javadoc
If you are trying to make some kind of "component" then it's better to convert the JSP page into a custom tag. Here is excellent article about that: http://onjava.com/pub/a/onjava/2004/05/12/jsp2part4.html