我试图阻止在用户名字段中提交的特殊字符,如(&,%, - ,>,<)。下面是我写的代码,但它没有得到遵守我得到错误(未封闭的字符文字)。请告诉我我在做什么错,这是阻止这些特殊字符的正确方法吗?
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;
}
}
答案 0 :(得分:1)
我在代码中看到了一些错误。您使用基元(char)作为对象(等于方法)。此外,您不要在要测试的字符周围加上引号。你应该像这样比较字符
u == '%'
我看到你也比较了一个字符串“ - ”,但同样的,这是错的,你应该使用
"--".equals(u)
我忘了添加,在比较单引号char时应该使用'\''。
如果您希望使用对象进行测试,可以使用该行创建一个Character对象:
Character u = aa.charAt(i);
但是因为你的代码很简单,所以我觉得它不是很有用。
答案 1 :(得分:1)
你有一些基本的语法错误,包括字符文字,例如u.equals(%)
应该是u.equals('%')
等,但如果使用正则表达式,你可以抛出大部分代码:
boolean ok = !username.matches(".*[%<>&;'\0-].*");
方括号中的字符是字符类,表示“列出的字符中的任何一个”。如果输入中有任何这些字符,整个表达式将匹配,因此否定这样的匹配意味着用户名不包含非法字符。
答案 2 :(得分:0)
如果您阻止这些字符,您的应用程序仍然容易受到XSS攻击。你错过了一些危险的。 而不是尝试识别坏字符(黑名单),为什么不检查它只包含允许的字符(白名单)。通常,允许的字符集非常有限。
另请参阅OWASP XSS预防备忘单。
答案 3 :(得分: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/