Question

I am using the below mentioned boolean statement to know if the string i got from the input box contains any special character. I want to know is it a good way to prevent XSS attack and can this filter be bypassed ?

!id.matches(".*[%#^<>&;'\0-].*")

Here's the complete code

package pack.java;

import pack.java.findrequestmodel;
import java.io.*;
import java.lang.*;
import org.apache.commons.lang.StringEscapeUtils;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class findrequestcontrol extends TagSupport
{
    HttpServletRequest request;
    HttpServletResponse response;

    public int doStartTag() throws JspException
    {
        request = (HttpServletRequest) pageContext.getRequest();
        response = (HttpServletResponse) pageContext.getResponse();

        return EVAL_PAGE;
    }

    public ResultSet check()
    {
        JspWriter out = pageContext.getOut();
        Connection con;
        ResultSet rs = null;
        CallableStatement stmt;
        String checkreq = "";
        String reqnum = (String) findrequestmodel.requestno.trim();

        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        }
        catch (ClassNotFoundException ex)
        {
        }
        try
        {
            if (!reqnum.matches(".*[%#^<>&;'\0-].*") )
            {
                con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","gaurav","oracle");
                stmt=con.prepareCall("begin requestdetail(?); end;");
                stmt.setString(1,reqnum);          
                rs=stmt.executeQuery();
            }
            else
                out.println("Invalid Number");
        }
        catch(SQLException ex)
        {
        }
        catch(Exception ex)
        {
        }

        return rs;
    }

    public int doEndTag() throws JspException
    {   
        JspWriter out=pageContext.getOut();
        ResultSet rs=check();

        try
        {      
            if (!rs.next()) 
            {  
                out.println("no data found");  
            }  
            else
            {   
                out.println("<table border=2>");
                out.println("<tr>");
                out.println("<th>EmployeId</th>");
                out.println("</tr>");

                do 
                {
                    out.println("<tr>");
                    out.println("<td>"+rs.getString(1)+"</td>");
                    out.println("</tr>");
                } while (rs.next());
            }

        }
        catch(Exception ex)
        {
        }

        return super.doEndTag();
    }
}

Below is the jsp page, the string is entered here and on submit redirects to a different page where tag is called.

<html>
    <head>
    </head>
    <body>
        <form method=post>
            <input type=text style="color:grey" name=reqno </br>
            <input type = submit name = submit value = Submit>

            <%
                String r=request.getParameter("reqno");
                String btn=request.getParameter("submit");

                HttpSession session1=request.getSession();
                session1.setAttribute("requestno",r);

                if (btn != null)
                    response.sendRedirect("findrequest1.jsp");
            %>
        </form>
    </body>
</html>

Here the tag is invoked

<jsp:useBean id="MrBean" class="pack.java.findrequestmodel"/>
<jsp:setProperty name="MrBean" property="requestno" value=""/>
<%@ taglib uri="/WEB-INF/jsp2/taglib8.tld" prefix="easy" %>
<html>
    <head>
    <body>
        <form method=post>
            <input type = submit name = submit value = Back>
            <%
                HttpSession mysession = request.getSession();
                String req = (String) mysession.getAttribute("requestno");

                MrBean.setRequestno(req);

                String btn = request.getParameter("submit");

                if (btn != null)
                    response.sendRedirect("findrequest.jsp");
            %>
            <easy:myTag8/>
        </form>
    </body>
</html>

No correct solution

OTHER TIPS

In fact what you want is to prevent XSS attacks using specials character. So you don't really have to care about the characters present in the String. You just have to espace them before doing any operation on your database, using a function with the same purposes as htmlspecialchars() in PHP.

Obviously such conversion can also be done in Java.

To replace all HTML entities (source) :

String source = "Escape the less than sign (<) and ampersand (&)";
String escaped = StringEscapeUtils.escapeHtml(source);
// Will output "Escape the less than sign (&lt;) and ampersand (&amp;)"

To replace only a select subset of characters (source) :

String escaped = StringUtils.replaceEach(source, new String[]{"&", "<"}, new String[]{"&amp;", "&lt;"});

EDIT :

To take your example, you would have to espace special characters in the variable reqnum because you'll use it in your SQL request :

String checkreq="";
String reqnum=(String)findrequestmodel.requestno.trim();
reqnum = StringEscapeUtils.escapeHtml(reqnum); // Espace special characters
// ... skipped code ...
rs=stmt.executeQuery(" select * from myadmin where reference_no='"+reqnum+"'"); // Safe

Alternative (and better) solution

You should not handle this by yourself, but use something called PreparedStatement which can do it for you, plus other useful stuff.

Server side code:

<input type="text" name="something" value="<%= something %>">

Attack:

" onfocus=alert(1) autofocus b=

Result:

<input type="text" name="something" value="" onfocus=alert(1) autofocus b=">

Input validation is not likely to block all XSS attacks. Focus on output escaping: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top