繁体   English   中英

如何过滤输入文本中的特殊字符以防止Java中的XSS攻击?

[英]How to filter special characters in input text to prevent XSS attack in java?

我正在尝试阻止在用户名字段中提交特殊字符,例如(&,%,-,>,<)。 以下是我编写的代码,但未得到编译,但出现错误(未封闭的字符文字)。 请告诉我我在做什么错,这是阻止这些特殊字符的正确方法吗?

  package pack.java;
  import pack.java.MyModel;
  import java.io.*;
  import java.lang.*;
  import javax.servlet.*;
  import javax.servlet.http.*;
  import javax.servlet.jsp.*;
  import javax.servlet.jsp.tagext.*;
  import java.sql.*;
  public class MyController extends TagSupport
  {

HttpServletRequest request;
HttpServletResponse response;
String msg="";
 String empid="";
public int doStartTag()throws JspException
{

     request=(HttpServletRequest)pageContext.getRequest();              
     response=(HttpServletResponse)pageContext.getResponse();
    return EVAL_PAGE;
   }    

   public void check()
 {

   HttpSession mysession=request.getSession();
   Connection con;
   CallableStatement stmt;
   ResultSet rs;
   JspWriter out=pageContext.getOut();
   int f=0;
     try
    {
   Class.forName("oracle.jdbc.driver.OracleDriver");
    }
       catch(ClassNotFoundException ex)
    {
       msg=ex.getMessage();
     }
    try 
   {


    String aa=(String)MyModel.name.trim();
    String bb=(String)MyModel.pass.trim();
    String cc="";
    String dd="";
     int i;
     int user =aa.length();
     int pass = bb.length();
     for (i=0; i<user; i++)
    {
    char u = aa.charAt(i);

    if ( u.equals(%) || u.equals(<) || u.equals(>) || u.equals(&) || u.equals(;) || 

         u.equals(') || u.equals(--) || u.equals(0))
    {
    out.println("Invalid Username !");
    }
     else 
    {
              cc+= u.toString();
    }
  } 
 con= DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:XE","gaurav","oracle");
    stmt=con.prepareCall("select usercheck1(?,?) from dual");
    stmt.setString(1,cc);
    stmt.setString(2,bb);       
    rs=stmt.executeQuery();

  try
 {
   while (rs.next())
 {
   empid=rs.getString (1);     
  mysession.setAttribute("user",empid);
   if(empid!=null)
 {
  response.sendRedirect("/Myjsp/selectaction.jsp");
  }
  else
  out.println("InValid User");
  }
 }
  catch(Exception ex)
 {
   msg=ex.getMessage();
 }

 }
catch(SQLException ex)
 {
  msg=ex.getMessage();
  }
 } 
   public int doEndTag() throws JspException
 {  
    check();
   return EVAL_PAGE;
  }
 }

我在您的代码中看到一些错误。 您将原语(char)用作对象(等于方法)。 另外,您不要在要测试的字符周围加引号。 你应该像这样比较字符

u == '%'

我看到您也比较了字符串“-”,但是同样,这是错误的,您应该使用

"--".equals(u)

我忘了补充,比较单引号char时应使用“ \\”。

如果您希望使用一个对象进行测试,则可以使用该行创建一个Character对象:

 Character u = aa.charAt(i);

但是由于您的代码很简单,所以我认为它没有真正的用处。

您在使用字符常量时会u.equals(%)一些基本的语法错误,例如u.equals(%)应该是u.equals('%')等,但是如果使用正则表达式,则可以丢弃大部分代码:

boolean ok = !username.matches(".*[%<>&;'\0-].*");

方括号中的字符是一个字符类 ,表示所列字符中的“任何一个”。 如果输入中有任何字符,则整个表达式将匹配,因此, 如果不匹配,则用户名包含非法字符。

您应该结合使用ESAPI,JSoup和JSR-303的@SafeHtml批注,以防止XSS并在存储有害值之前将其过滤掉。

package com.domain.security.filter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.MultivaluedMap;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Entities.EscapeMode;
import org.jsoup.safety.Whitelist;
import org.owasp.esapi.ESAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;

public class XSSFilter implements ContainerRequestFilter
{
    private static final Logger LOG = LoggerFactory.getLogger( XSSFilter.class );

    /**
     * @see ContainerRequestFilter#filter(ContainerRequest)
     */
    @Override
    public ContainerRequest filter( ContainerRequest request )
    {
        // Clean the query strings
        cleanParams( request.getQueryParameters() );

        // Clean the headers
        cleanParams( request.getRequestHeaders() );

        // Clean the cookies
        cleanParams( request.getCookieNameValueMap() );

        // Return the cleansed request
        return request;
    }

    /**
     * Apply the XSS filter to the parameters
     * @param parameters
     * @param type
     */
    private void cleanParams( MultivaluedMap<String, String> parameters )
    {
        LOG.debug( "Checking for XSS Vulnerabilities: {}", parameters );

        for( Map.Entry<String, List<String>> params : parameters.entrySet() )
        {
            String key = params.getKey();
            List<String> values = params.getValue();

            List<String> cleanValues = new ArrayList<String>();
            for( String value : values )
            {
                cleanValues.add( stripXSS( value ) );
            }

            parameters.put( key, cleanValues );
        }

        LOG.debug( "XSS Vulnerabilities removed: {}", parameters );
    }

    /**
     * Strips any potential XSS threats out of the value
     * @param value
     * @return
     */
    public String stripXSS( String value )
    {
        if( value == null )
            return null;

        // Use the ESAPI library to avoid encoded attacks.
        value = ESAPI.encoder().canonicalize( value );

        // Avoid null characters
        value = value.replaceAll("\0", "");

        // Clean out HTML
        Document.OutputSettings outputSettings = new Document.OutputSettings();
        outputSettings.escapeMode( EscapeMode.xhtml );
        outputSettings.prettyPrint( false );
        value = Jsoup.clean( value, "", Whitelist.none(), outputSettings );

        return value;
    }
}

以及使用JSR-303的示例

import org.hibernate.validator.constraints.SafeHtml;
import org.hibernate.validator.constraints.SafeHtml.WhiteListType;

public class MySecureModel {
    @SafeHtml( whitelistType = WhiteListType.NONE )
    private String userInput;
}

这是一个使用Jersey 1.x和2.x的示例,可以轻松将其改编/更改为常规HTTP过滤器: http : //codehustler.org/blog/jersey-cross-site-scripting-xss-filter-for- java-web-apps /

如果您阻止这些字符,您的应用程序仍然容易受到XSS的攻击。 您缺少一些危险的东西。 与其尝试识别坏字符(黑名单),不如检查它是否仅包含允许的字符(白名单)。 通常,允许的字符集非常有限。

另请参阅OWASP XSS预防备忘单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM