转载请注明转载自:
http://hi.baidu.com/liheyuan87/
SQL注入已经延伸到了JSP……所以我们必须提高警惕,本类可以对表单提交数据中(POST)的注入攻击做有效的防范,也可以对部分Get中的攻击做防范。并且自动过滤html标签和js代码。自动解决mysql入库时候单引号,双引号导致SQL语句出错的问题。
OK。切入正文。
现来使用方法
1、把类拷贝到filters包下
2、在web.xml中添加FIlter定义和映射,注意,建议把本Filter放在所有Filter的最后
3、web.xml定义如下
<filter>
<description>解决SQL注入问题</description>
<filter-name>SQLInjectionFilter</filter-name>
<filter-class>filters.SQLInjectionFilter</filter-class>
<init-param>
<description>要被过滤掉的字符列表,空格分开</description>
<param-name>delete</param-name>
<param-value>and exec insert select delete update count chr mid master truncate char declare</param-value>
</init-param>
<init-param>
<description>要过滤的表单参数名,用空格分开,不在本列表中的参数将不被过滤,以提高效率</description>
<param-name>param</param-name>
<param-value>tag content</param-value>
</init-param>
</filter>
这里要说明的是,两个Filter预设参数
1、delete:所有要过滤的词,您可以自行添加,注意用空格分开。
2、param:因为只有对于部分参数我们才有必要过滤,所以,在这里指定要过滤的参数名,用空格分开,例如:user pass content title
3、您可以继续添加其他的过滤词汇作为参数,参数名是待替换词汇,参数值是被替换词汇。
映射没什么好说的。。
<filter-mapping>
<filter-name>SQLInjectionFilter</filter-name>
<url-pattern>/poststore</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
转载请注明转载自:http://hi.baidu.com/liheyuan87/
源代码:SQLInjectionFilter.java
package filters;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* 过滤提交表单中的有安全隐患的字符串,以防止SQL注入
* 使用方法:在Filter映射中加入2个参数
* 参数1:delete,用于指定被过滤掉的词汇,用空格分开,例如:delete insert
* 参数2:需要过滤的表单参数名,用空格分开,例如:user pass
* @author lhy
* @version 1.0
*/
public class SQLInjectionFilter implements Filter {
// The filter configuration object we are associated with. If
// this value is null, this filter instance is not currently
// configured.
private FilterConfig filterConfig = null;
private static LinkedList<Pair> wordMap = null;
private static HashSet<String> paramSet = null;
public SQLInjectionFilter() {
}
//从Servlet参数中读取Words替换规则并存入wordMap中
private void doBeforeProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if(wordMap==null || paramSet==null)
{
wordMap = new LinkedList<Pair>();
paramSet = new HashSet();
Enumeration enums = filterConfig.getInitParameterNames();
while(enums.hasMoreElements())
{
String key = (String)enums.nextElement();
String value = filterConfig.getInitParameter(key);
if(key.equals("delete"))
{
for(String s:value.split(" "))
{
wordMap.add(new Pair(s, ""));
}
}
else if(key.equals("param"))
{
for(String s:value.split(" "))
{
paramSet.add(s);
}
}
else
{
wordMap.add(new Pair(key, value));
key = null;
value = null;
}
}
//其他不好在Filter中过滤的符号,也可以顺便解决数据库入库时候的非法符号
wordMap.add(new Pair("\"", "" "));//双引号
wordMap.add(new Pair("\'", "''"));//单引号用''替代
wordMap.add(new Pair("&", "& "));//&
wordMap.add(new Pair("<[^>]*>", ""));//超级无敌的正则……替换掉所有的HTML和JS、CSS标签
}
}
private void doAfterProcessing(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
//
// Write code here to process the request and/or response after
// the rest of the filter chain is invoked.
//
//
// For example, a logging filter might log the attributes on the
// request object after the request has been processed.
//
/*
for (Enumeration en = request.getAttributeNames(); en.hasMoreElements(); ) {
String name = (String)en.nextElement();
Object value = request.getAttribute(name);
log("attribute: " + name + "=" + value.toString());
}
*/
//
//
// For example, a filter might append something to the response.
//
/*
PrintWriter respOut = new PrintWriter(response.getWriter());
respOut.println("<P><B>This has been appended by an intrusive filter.</B>");
*/
}
/**
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param chain The filter chain we are processing
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
doBeforeProcessing(request, response);
Throwable problem = null;
try
{
request = new NewWrapper((HttpServletRequest)request,wordMap,paramSet);
chain.doFilter(request, response);
}
catch(Throwable t) {
//
// If an exception is thrown somewhere down the filter chain,
// we still want to execute our after processing, and then
// rethrow the problem after that.
//
problem = t;
t.printStackTrace();
}
doAfterProcessing(request, response);
//
// If there was a problem, we want to rethrow it if it is
// a known type, otherwise log it.
//
if (problem != null) {
if (problem instanceof ServletException) throw (ServletException)problem;
if (problem instanceof IOException) throw (IOException)problem;
sendProcessingError(problem, response);
}
}
/**
* Return the filter configuration object for this filter.
*/
public FilterConfig getFilterConfig() {
return (this.filterConfig);
}
/**
* Set the filter configuration object for this filter.
*
* @param filterConfig The filter configuration object
*/
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
/**
* Destroy method for this filter
*
*/
public void destroy() {
}
/**
* Init method for this filter
*
*/
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
/**
* Return a String representation of this object.
*/
public String toString() {
if (filterConfig == null) return ("SQLInjectionFilter()");
StringBuffer sb = new StringBuffer("SQLInjectionFilter(");
sb.append(filterConfig);
sb.append(")");
return (sb.toString());
}
private void sendProcessingError(Throwable t, ServletResponse response) {
String stackTrace = getStackTrace(t);
if(stackTrace != null && !stackTrace.equals("")) {
try {
response.setContentType("text/html");
PrintStream ps = new PrintStream(response.getOutputStream());
PrintWriter pw = new PrintWriter(ps);
pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
// PENDING! Localize this for next official release
pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
pw.print(stackTrace);
pw.print("</pre></body>\n</html>"); //NOI18N
pw.close();
ps.close();
response.getOutputStream().close();;
}
catch(Exception ex){ }
}
else {
try {
PrintStream ps = new PrintStream(response.getOutputStream());
t.printStackTrace(ps);
ps.close();
response.getOutputStream().close();;
}
catch(Exception ex){ }
}
}
public static String getStackTrace(Throwable t) {
String stackTrace = null;
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
sw.close();
stackTrace = sw.getBuffer().toString();
}
catch(Exception ex) {}
return stackTrace;
}
public void log(String msg) {
filterConfig.getServletContext().log(msg);
}
public static void main(String args[])
{
String str="select";
}
}
class Pair
{
public String key;
public String value;
public Pair(String k,String v)
{
key = k;
value = v;
}
}
class NewWrapper extends HttpServletRequestWrapper
{
private LinkedList<Pair> wordMap;
private HashSet<String> paramMap;
public NewWrapper(HttpServletRequest req,LinkedList<Pair> map,HashSet m2)
{
super(req);
wordMap = map;
paramMap = m2;
}
public String getParameter(String str)
{
try
{
String param = super.getParameter(str);
if(!paramMap.contains(str))
{
//如果不包含在被过滤列表中,直接返回
return param;
}
Iterator<Pair> itr = wordMap.listIterator();
while(itr.hasNext())
{
Pair p = itr.next();
param = param.replaceAll(p.key, p.value);
}
return param.trim();
}
catch (Exception e)
{
return null;
}
}
}
转载请注明转载自:http://hi.baidu.com/liheyuan87/
学JSP不到2周,不当之处请大家多多指教。
不错