When I use the below jstl code
<a href="http://mysite.com?id="<c:out value="${myid}"/>/><c:out value="${myid}"/></a>
the output is :
"1234"
The value 1234 corresponds to the variable value of myid but the url being generated is
"http://mysite.com?id=" so no value for myid is being generated as part of the href.
How can I amend the href so that entire href is displayed :
"http://mysite.com?id=1234"
instead of :
"http://mysite.com?id="
Ultimately, JSP/JSTL generates HTML. You're familiar with basic HTML, right?
Look closer at the generated HTML output by rightclick, View Source in browser. You'll see:
<a href="http://mysite.com?id="1234/>1234</a>
Is that valid HTML? No, you're closing the attribute value too soon with " at wrong place and you're closing the tag too soon with />. Look, the Stack Overflow HTML syntax highlighter also got confused. Instead, it should have been:
1234
Fix the HTML generator (i.e. the JSP/JSTL code) accordingly so that it generates the desired HTML:
<c:out value="${myid}"/>
Unrelated to the concrete problem, the <c:out> is only helpful in preventing XSS attack holes when redisplaying user-controlled input and actually the wrong tool to inline URL parameters. If you can guarantee that ${myid} is always a number (because it's a Long or Integer), you can even just leave it entirely out, making the code prettier to read:
${myid}
If the ${myid} is however not a guaranteed to be a number (because it's a String), then you should use <c:url> and <c:param> to properly URL-encode it:
<c:url value="http://mysite.com" var="myURL">
<c:param name="id" value="${myid}" />
</c:url>
<c:out value="${myid}" />
<c:url> tag is used to create an url. It is helpful in the case when cookies is turned off by the client, and you would be required to rewrite URLs that will be returned from a jsp page.
<c:param> tag may used as a subtag of to add the parameters in the returned URL. Using these parameters encodes the URL.
<c:url value="http://mysite.com" var="myURL">
<c:param name="id" value="${myid}" />
</c:url>
<a href="${myURL}" />${myURL}</a>
Read more from here.
Related
I'm currently working on a Spring MVC project where we are migrating all our jsp files to thymeleaf. I'm aware that the spring form tag has an htmlEscape attribute that will escape user input when rendering, such as when the user submits an invalid form and the user input is rendered bound to the form. An example of this:
<form:form method="post" id="someForm" modelAttribute="${commandName}" htmlEscape="true" autocomplete="off">
<div class="form-group">
<input type="text" id="username" value="<c:out value='${inputValue}'/>"/>
<input type="password" id="password" />
<input type="submit" class="btn btn-lg btn-block-sm" value="<spring:message code="header.content.close"/>" tabindex="0" />
<input type="hidden" name="_eventId" value="continue"/>
</div>
</form:form>
This fits under the umbrella of output-escaping, which is something that happens on the server side when processing a template to render.
An example of an xss attack this prevents is if the user entered
<script>alert("gotcha");</script> for the username, and some arbitrary value for the password. The form will rerender with the entered username bound to the form. The htmlEscape="true" attribute in the form tag will cause this output to be escaped to mitigate xss. So the username field will contain <script>alert("gotcha");</script> when the bound form rerenders with the error, instead of the actually entered valid html
Is there a standard way to achieve this same functionality in thymeleaf?
A few possibilities I see:
This is already built into thymeleaf.
I'm aware that the spring thymeleaf package uses unbescape to perform output escaping on some attributes, for example SpringValueTagProcessor which I believe escapes output on th:value attributes. However, I'm not sure this is equivalent, and fear there may be security holes left unfilled if this was done in a way that only partially mitigates what the spring form htmlEscape fully mitigates.
If so, please explain how this covers the same cases that htmlEscape does.
There is an existing Spring / Spring MVC solution that is flexible enough to not rely on jsp.
If so, what?
There is a common solution to this for thymeleaf which involves some modification of the template parsing engine.
If so, please explain.
Here is a brief article to give you an idea of what I mean regarding the spring form behavior. Regarding this article, it appears that setting the defaultHtmlEscape to false globally in the web.xml only overrides the default value of HtmlEscapeTag, which appears to only work for spring tags. Thus I don't think the solution can be applied to thymeleaf.
I would appreciate any direction here.
Escaping of output text is done automatically if you use th:text. In rare cases, you can use th:utext if you want to use unescaped text, but you have to be aware of the security implications. See Process thymeleaf variable as html code and not text for some more info.
I ended up getting an answer on the GitHub discussions for the Thymeleaf project here, which I will summarize and clarify:
HTML escaping is built into Thymeleaf form elements by default.
This is evidenced by th:input processor source code. Note the use of getDisplayString which performs html output escaping via org.springframework.web.util.HtmlUtils
I went through and manually checked all the uses of getDisplayString where htmlEscape is false and can verify that in these cases, the output is HTML escaped before displaying (in the case of SpringErrorTagProcessor and SpringUErrorsTagProcessor), they don't output any content to escape (SpringSelectedValueComparator returns a boolean), or the expression is a bound object (SPELVariableExpressionEvaluator).
See GitHub issue thymeleaf/thymeleaf-docs#84 for information regarding the docs being updated accordingly.
Using spring form, we display an input like this:
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
...
<form:input type="text" cssClass="w50" path="lastName" cssErrorClass="w50 error" placeholder="${msgLastName}" />
Sometimes, the users lastname value may content single quote, eg "Job's". This probkem is that we clean the lastname with the OWASP HTML Project, which causes the lastname to be
Job's
When the input is displayed into the browser, the ascii value is also displayed - whici is bad. I would like to display simply "Job's" into the input.
I tested with a simple JSP input, eg.
<input type="text" cssClass="w50" value="${myobject.lastName}" cssErrorClass="w50 error" placeholder="${msgLastName}" />
In this case, the rendering is fine.
My conclusion is that the problem comes from spring, but how to avoid it?
Finally found the answer.
Spring HTML-escapes the values, it doesn't really output
Job's
but
Job's
As there is an HTML character, it isn't parsed as ascii.
Using Chrome, if I inspect the DOM I cannot see the
&
but if I "edit as HTML" then I see it.
What I have:
I have a generic JSP page that is used throughout my application for displaying certain entities. The code that I am interested in goes like this:
<form:form modelAttribute="object"/>
<core:forEach items="${sections}" var="section" varStatus="itemStat">
<core:forEach items="${section.fields}" var="fieldDef">
<form:input path="${fieldDef.fieldName}"/>
</core:forEach>
</core:forEach>
<form:form>
For each section, and for each field in that section, I have an input having the path fieldName, which is what I want to display from each field.
What I want:
I would like instead of the input to be a simple text, like a label.
What I have tried:
I am most certain that I can do it somehow with <form:label> but I can't really make it work. Making a <form:label path="${fieldDef.fieldName}" /> just tells the browser for which field I need the label, but doesn't get the actual value from it.
I have also tried something like ${object.fieldDef.fieldName}, but in order for this to work I would have to first analyze the value of ${fieldDef.fieldName}, which would give me the name of the column, and then do a ${object.column}, but column being a variable I haven't been able to make this work in any way.
Alternative:
An alternative would be to just make the inputs as disabled and remove the border with CSS, but that would be a dirty way and from what I saw it is also tricky for IE different versions. I am sure that I can handle it directly.
I am a little intrigued by the fact that <form:input path="..."> puts into the input what it finds corresponding to that path (same goes for other form elements), but with label it works different.
So, what I want is basically simple, but I haven't managed to find a way. If someone could shed some light, that would be great. Thanks in advance !
You could look into the spring bind tag. I haven't tried using it before but this may work for you, in place of the input tag
<spring:bind path="fieldDef.fieldName">
${status.value}
</spring:bind>
reference: http://static.springsource.org/spring/docs/1.1.5/taglib/tag/BindTag.html
Instead of
<form:input path="${fieldDef.fieldName}"/>
use
<c:out value="${fieldDef.fieldName}"/>
It would display whatever value is there instead of creating a input field. Hope this helps you. Cheers.
Using the spring form tab, one option would be to use
<form:input disabled="true" path="${fieldDef.fieldName}"/>
To further make it not look like an input you could use CSS to style it to your preference.
Some css styles you could use:
background-color:#EEEEEE;border: 0px solid;
Update:
You could look into the spring bind tag. I haven't tried using it before but this may work for you, in place of the input tag
<spring:bind path="fieldDef.fieldName">
${status.value}
</spring:bind>
I have seen several examples using
<a href="<spring:url value='/about/' />" >About </a>
I try this and get an error from Jetty
Caused by: org.apache.jasper.JasperException: /WEB-INF/views/footer.jspx(6,22) The value of attribute "href" associated with an element type "null" must not contain the '<' character.
Is there some encoding setting I have overlooked?
This is unfortunate because the other examples of using spring url I have seen are ugly
<spring:url value='/about' var="about_url" />
About MyFit
Do I really need an additional line for every hyperlink in my templates?
Is this something that is fairly trivial and I have overlooked?
You have a .jspx file, which must be a well-formed XML document. In .jsp files it would work fine.
What's the proper way to create a hyperlink in Spring+JSP? There must be a better way than just coding in the <a href="..."> tag. Take for example a page that displays people. The URL is people.htm. The corresponding controller gets people from the database and performs optional column sorting. The JSP might look like:
<table>
<tr>
<td>Name</td>
<td>Age</td>
<td>Address</td>
</tr>
...
This seems bad as the URL people.htm is hardcoded in the JSP. There should be a way to have Spring automatically build the <a> tag using the URL defined in servlet.xml.
Edit: Maybe I should be using a Spring form.
The only thing that comes to mind is the JSTL standard tag <c:url>. For example:
<c:url var="thisURL" value="homer.jsp">
<c:param name="iq" value="${homer.iq}"/>
<c:param name="checkAgainst" value="marge simpson"/>
</c:url>
Next
Now this won't get you servlet mapping or the like but nothing will. It's not something you could really do programmatically (after all, a servlet can and usually does map to a range of URLs). But this will take care of escaping for you.
I haven't seen this kind of functionality in pure spring (although grails offers things like that).
For your specific case you might consider removing the file part and only using the query string as the href attribute:
<td>Name</td>
<td>Age</td>
<td>Address</td>
These links append the query string to the path component of the current url.
In Spring MVC in jsp:
You can use:
General Hyperlink:
Click Here
If passing from controller:
Click Here
Jsp tags
<c:url var="URL" value="login">
<c:param name="param" value="${parameter}"/>
</c:url>
Click Here
Hope it Helps.. :)
Better way to create link is:
Name
<%=request.getContextPath() %> makes sure that correct URI will be taken into account.
"sort" parameter you can get over with hidden field and change a value with a little bit of javascript:
<input type="hidden" name="sort" id="sort" value="name">
And controller method should look like this:
#RequestMapping("/people")
public String createUser(String sort) {
...
}
Import this package in your jsp file
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
when you want to redirect new page or url then use for eg.
<a href='<c:url value="url of next page" />'>Home</a>