Given
// Java abstract code
labelName = '<script> alert('xss'); </script>'
// JSP
<%# taglib uri="org.company.tag.tagobject" prefix="tagobject" %>
<tagobject:labelName/>
Expected result
JSP shows string properly without accidental JavaScript code activation
Actual result
JSP taglib tag activates JavaScript (thus can be easily used for XSS)
// Result from code at the start
shows alert with text xss
I tried:
<c:out value="<tagobject:labelName/>" />
<c:out value="${fn:escapeXml(tagobject:labelName)}" />
But it doesn't work.
Steps to reproduce:
taglib file tags.tld:
<tlib-version>1.0</tlib-version>
<jsp-version>2.2</jsp-version>
<short-name>org</short-name>
<uri>org.company.tag.tagobject</uri>
<tag>
<name>labelName</name>
<tag-class>org.company.tag.LabelName</tag-class>
<attribute>
<name>plural</name>
<required>false</required>
</attribute>
<body-content>empty</body-content>
</tag>
</taglib>
java class LabelName:
private void writeDescriptor (String descriptor) throws JspException, IOException {
final JspWriter writer = getJspContext().getOut();
writer.print(descriptor);
}
jsp file home.jsp
<%# taglib uri="org.company.tag.tagobject" prefix="tagobject" %>
<tagobject:labelName/>
write something into string variables of that tagobject, so they are used as descriptors and shown at jsp.
Part 2 String descriptor already contains string representation of JavaScript, so that probably I can filter JavaScript code there.
Probably c:out or fn:escapeXml can be used there but I'm not sure how. Also I'm not sure which code is needed to explain better.
First solution
I've tried to filter string on part of Java custom tags (step 2, in java class LabelName). Found library for this named owasp-java-html-sanitizer.
So, now LabelName class looks like this:
private void writeDescriptor (String descriptor) throws JspException, IOException {
final JspWriter writer = getJspContext().getOut();
String safeString = new HtmlPolicyBuilder().toFactory().sanitize(descriptor);
writer.print(safeString);
}
Have not checked all the possible xss inputs but at least it removes simplest ones i've checked.
Related
I'm trying to pass a parameter to the jsp file that I am including in my main jsp. From what I've seen online the way to do this using c:set
approot/index.jsp
<c:set var="Arg01" value="Argument01"/>
<jsp:include page="include/other.jsp">
<jsp:param name="myArg01" value="${Arg01}"/>
<jsp:param name="myArg02" value="Argument02"/>
</jsp:include>
Although when I try to use the variables in the included jsp page only the one argument seems to be coming through (the second one which is not using c:set)
approot/include/other.jsp
<!-- this doesn't work -->
<p>${param.myArg01}</p>
<!-- this does -->
<p>${param.myArg02}</p>
Nothing crashes but I can see that myArg01 is blank
This way of getting around it is probably awful but it's the only way I could find to get around the issue.
I used a different kind of include in my main JSP
public static String myArg01 = "Argument01";
public static String myArg02 = "Argument02";
<%# include file="include/other.jsp" %>
Then I could reference the variables directly inside the included JSP file
<p><%= myArg01 %></p>
<p><%= myArg02 %></p>
I am pretty new to custom tag creation in JSP. When I went through some tutorials, I saw them using EVAL_BODY_AGAIN, SKIP_BODY and EVAL_BODY_INCLUDE tags. Can anyone tell me what it actually means and what is it for?
SKIP_BODY : It is an optional returned value but this value must be returned by doStartTag() when you want to skip the body evaluation that is it must be returned when the TagLibraryDescriptor file contains the element empty, the value "empty" shows that there will always be an empty action.
EVAL_BODY_INCLUDE : It is an optional returned value but this value must be returned by the doStartTag() when you want to evaluate the body.
Example :
consider a class DoStartTagExample.java
package pack;
import javax.servlet.jsp.tagext.TagSupport;
public class DoStartTagExample extends TagSupport
{
public int doStartTag()
{
//return EVAL_BODY_INCLUDE;
return SKIP_BODY;
}
}
This is a sample tld called doStartTagExample.tld
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<tag>
<name>doStart</name>
<tag-class>pack.DoStartTagExample</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
now write a jsp doStartTagExample.jsp
<%#taglib uri="/WEB-INF/doStartTagExample.tld" prefix="dev" %>
<html>
<head>
<title>doStartTag() Example</title>
</head>
<body>
Jsp page content before starting tag.
<dev:doStart>
<br><b>contents displayed after the custom tag's
start tag is encountered.</b>
</dev:doStart>
<br>Jsp page content after closing tag.
</body>
</html>
Output will be as follows
I've spent a day looking for the right solution, but no luck!
The question is that how to call java constant variables from jsp with el ${bean.objectName} for example. What is the best practice?
I wonder if this is doable, im quite new to Spring and jsp.
Constant class:
public class RNConstant {
public static final String HELLO_WORLD = "Hello World again!";
public static final String DEFAULT_LOCALE = "id_ID";
public static final String CONTEXT_PATH_SOAP_SR = "soap.sr";
}
Expectation in jsp to be called with EL
<p>${RNConstant.HELLO_WORLD}</p>
I could do this with scriptlet as below, but i could not get this working if it runs in weblogic. This works in apache tomcat v7 or v8
<%# page import="static id.co.telkom.common.RNConstant.*" %>
...
...
<%= HELLO_WORLD %>
Error in weblogic
home.jsp:2:18: Syntax error on token "static", Identifier expected after this token
<%# page import="static id.co.telkom.common.RNConstant.*" %>
^-------------------------------------^
home.jsp:11:19: HELLO_WORLD cannot be resolved
Hello world! <%=HELLO_WORLD%>
^--------^
java version: 1.6
pom.xml
spring
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>3.2.8.RELEASE</org.springframework-version>
<org.springjs-version>2.0.5.RELEASE</org.springjs-version>
<org.springws-version>2.2.1.RELEASE</org.springws-version>
<org.springsecurity-version>3.2.3.RELEASE</org.springsecurity-version>
<jackson-version>1.9.10</jackson-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
Scriplet issue was solved with below codes, and Content of RNConstant is still the same.
<%# page import="id.co.telkom.common.RNConstant" %>
...
...
<%= RNConstant.HELLO_WORLD %>
Cheers,
Hendry
Keep the import statement simple
<%# page import="static id.co.telkom.common.RNConstant.*" %>
Remove ".*" after RNConstant. Also remove static word in the beginning.
<%# page import="id.co.telkom.common.RNConstant" %>.
To call HELLO_WORLD constant use
<p>${RNConstant.HELLO_WORLD}</p> <p>${RNConstant.HELLO_WORLD}</p>
Expectation in jsp to be called with EL
<p>${RNConstant.HELLO_WORLD}</p>
EL checks the bean and translates HELLOWORLD to getHELLOWORLD() because specs says that attributes must be accessed in this way, so you must create a getter or visibility for constants will be limited in jsp view:
public class RNConstant
{
public final static String HELLO_WORLD = "Hello World again!";
public static String getHELLO_WORLD() {
return HELLO_WORLD;
}
}
If you can't create getters check this answer
I have a filter that processes a given servlet mapping and includes a JSP that holds the structure of every page.
servletContext.getRequestDispatcher( "/index.jsp" ).include( request, response );
Inside the jsp I have a custom jstl tag that handles the inclusion of another JSP portion inside the parent according to a series of rules (the inclusion is done inside the "body" tag:
pageContext.include( ProcessURI.getJSPLocation( request.getRequestURI() ) );
Inside to the latest included JSP I want to be able to write a stylesheet and append to the response. I am using a taglib for that.
<taglib:head>
<link rel="stylesheet" href="some.css" >
</taglib:head>
Since the contents of the last JSP is included into the "body" tag I need to access the "head" and insert the HTML after the last item (I cannot insert the stylesheet inside the "body" tag).
<head>
...
<!-- I want to insert here -->
<link rel="stylesheet" href="some.css" >
<head>
<body>
...
How would I access the processed response inside the last taglib (taglib:head) where I can edit and insert its body content into the first included jsp (/index.jsp)?
I suppose it is possible to access the response that has been processed until the given taglib call, am I correct?
I accept different ways of achieving the same result using other techniques than mentioned above.
I have solved creating one taglib to load the file page.jsp and another one for page-head.jsp. In that way I process the data in the proper order without doing some crazy response manipulation.
This test was prompted by reading a question on the Sun java forums and thought I would try it out.
The JSP2.0 specification section JSP.13.8 contains an "Example Simple Tag Handler Scenario". I copy and pasted the code fragments and attempted to run it.
Environment:
Apache Tomcat version 5.5.26 and 6.0.14 (tested on both)
Java: 1.5
Code I am testing with:
Jsp page:
<%# taglib prefix="my" tagdir="/WEB-INF/tags" %>
<my:simpletag x="10">
<jsp:attribute name="y">20</jsp:attribute>
<jsp:attribute name="nonfragment">
Nonfragment Template Text
</jsp:attribute>
<jsp:attribute name="frag">
Fragment Template Text ${var1}
</jsp:attribute>
<jsp:body>
Body of tag that defines an AT_BEGIN
scripting variable ${var1}.
</jsp:body>
</my:simpletag>
And the tag file:
<%-- /WEB-INF/tags/simpleTag.tag --%>
<%# attribute name="x" %>
<%# attribute name="y" %>
<%# attribute name="nonfragment" %>
<%# attribute name="frag" fragment="true" %>
<%# variable name-given="var1" scope="AT_BEGIN" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Some template text.
<c:set var="var1" value="${x+y}"/>
<jsp:invoke fragment="frag" varReader="var1"/>
Invoke the body:
<jsp:doBody/>
This code is directly copied from the PDF copy of the JSP2.0 specification.
It is also available as part of the JSP-API here
Minor change made - I changed the name of the tagfile from simpletag.tag to simpleTag.tag to match the invocation of it in the JSP.
I also tried copying from the PDF of the spec (adjusting quotes as necessary) - same result.
When I execute the page I end up with a standard 500 error
Root cause:
java.lang.ClassCastException: java.io.StringReader
org.apache.jsp.tagVariableTest_jsp._jspService(tagVariableTest_jsp.java:62)
Line62 of the generated JSP turns out to be:
var1 = (java.lang.String) _jspx_page_context.findAttribute("var1");
Ok, I can understand ClassCastException - it thinks that var1 should be a String, and the actual attribute is a StringReader. But why is it a StringReader? Where did the variable get created? And why is it attempting to do this assignment at all?
Can someone please point me in the right direction?
What is wrong with the code/setup?
Is this a known issue? I googled for it but couldn't seem to find anything.
Thanks,
evnafets
Editing with resolution:
The ClassCastException was being caused by the line in the tag:
<jsp:invoke fragment="frag" varReader="var1"/>
As mentioned here the varReader attribute specifies the attribute to store the evaluation result as a StringReader. The exception was caused by Tomcat generated code trying to retrieve the value of "var1" and cast it to a String. As a String is not a StringReader so, it raised an exception at that point.
I'm not sure if the coding error is they should have used the "var" instead of the "varReader" attribute, or they shouldn't have used either and just evaluated it as is.
Removing that attribute completely prints out the fragment, and then the body both with the value of "var1":
Fragment Template Text 30.
Invoke the body: Body of tag that defines an AT_BEGIN scripting variable 30
Making the attribute var="var1" executes the fragment, and stores the result to var1. The body is then evaluated with this new value of var1 resulting in:
Invoke the body: Body of tag that defines an AT_BEGIN scripting variable Fragment Template Text 30
Personally I think the first case makes more sense, but this code is presented as an example of the innerworkings, not best practice.
I still would have expected the example to compile/run in any case. I was fairly surprised when it didn't.
From the syntax reference you can see that either var or varReader is
The name of a scoped attribute to store the result of the fragment invocation in
So I am afraid the sample code contains an error. If you need to write the result of jsp:invoke directly to the page you do not need to assign it to a var.
Can you try leaving out the "varReader" attribute?