출처 : http://shonm.tistory.com/m/post/425
웹 페이지 입력 란에
<script> alert('1111'); </script>
이런 식으로 입력을 하면 입력 정보를 불러 올 때 alert 가 뜨게 될 수 있는데...
이게 악성 스크립트를 전송 하여 클릭 시 PC 의 인증 정보를 수집하여
공격하는 Cross Site Scripting 이 가능 하다고 본다고 한다.
그래서 < , > 등을 입력 받지 못하도록 막아야 한다고 대형 사이트의 보안 권고
사항이 나온다.
JSP 개발 상황이라면 class 2개 를 만들고 web.xml 에 간단한 filter 추가로
해결 할 수 있다.
일단 servlet-api.jar 파일을 lib 폴더에 넣는다. (tomcat 등에 있다.)
그 다음 class 2 개를 추가 한다.
추가 해야 할 class 1
package com.incross.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class RequestWrapper extends HttpServletRequestWrapper {
public RequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values==null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = stripXSS(values[i]); //cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
//return cleanXSS(value);
return stripXSS(value);
}
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null){
return null;
}
//return cleanXSS(value);
return stripXSS(value);
}
private String cleanXSS(String value) {
//You'll need to remove the spaces from the html entities below
value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replaceAll("script", "");
// HTML transformation characters
value = org.springframework.web.util.HtmlUtils.htmlEscape(value);
// SQL injection characters
value = StringEscapeUtils.escapeSql(value);
return value;
}
public static String stripXSS(String value) {
if (value != null) {
// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
value = value.replaceAll("", "");
// Avoid anything between script tags
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid anything in a src='...' type of expression
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome <script ...> tag
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// HTML transformation characters
value = org.springframework.web.util.HtmlUtils.htmlEscape(value);
// SQL injection characters
value = StringEscapeUtils.escapeSql(value);
}
return value;
}
}
>>>>>>>>>> 내가 좀 손본거임...ㅎㅎ cleanXSS=>stripXSS
===============================================================
추가 해야 할 class 2
package com.incross.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class CrossScriptingFilter implements Filter {
public FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new RequestWrapper((HttpServletRequest) request), response);
}
}
================================================================
web.xml 에 추가 해야 할 사항
<filter>
<filter-name>XSS</filter-name>
<filter-class>com.incross.util.CrossScriptingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XSS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
================================================================
출처 : http://www.javablog.fr/java-security-cross-site-scripting-xss-and-sql-injection.html
A simple post concerning the Cross Site Scripting (XSS) and SQL injection which are types of security vulnerability used in Web applications. In SQL-Injection the vulnerability is exploited by injecting SQL Queries as user inputs. In XSS, Javascript code is injected (basically client side scripting) to the remote server (persistente or non-persistent). For more information, Wikipedia is a good source http://en.wikipedia.org/wiki/Cross-site_scripting andhttp://en.wikipedia.org/wiki/SQL_injection.
Cross Site Scripting (XSS)
XSS injects executable code via the GET or POST parameters in HTTP requests. So, here, I would present an example of special characters (<, >, ‘, …) transformation into their HTML code in order to not be executed by the browser.
An example of XSS attack could be filling javascript code in in form’s field:
1 | "/>< script >alert(xss attack);</ script > |
SQL injection
SQL injection is a code injection technique, used to attack data driven applications, in which malicious SQL statements are inserted into an entry field for execution.
A best-pratice is no use the concatenation of SQL queries and variables like:
1 | "SELECT id, name FROM TABLE_PERSON WHERE id=" +myIdVariable;" |
…instead, use the parametrized queries via the PreparedStatement.
An example of SQL injection could be:
1 | .../mycontext/myservice.do?name=12&id=123' AND '1'=='1'-- |
Solution and implementation
First, we create HTTP filter RequestWrappingFilter in order to intercept the HTTP request configured in the web.xml file:
1 | < filter > |
2 | < filter-name >RequestWrappingFilter</ filter-name > |
3 | < filter-class >com.huo.filter.RequestWrappingFilter</ filter-class > |
4 | </ filter > |
5 |
6 | < filter-mapping > |
7 | < filter-name >RequestWrappingFilter</ filter-name > |
8 | < url-pattern >/*</ url-pattern > |
9 | </ filter-mapping > |
… the goal of this filter is to wrapper the request into an own-coded wrapperMyHttpRequestWrapper which transforms:
- the HTTP parameters with special characters (<, >, ‘, …) into HTML codes via theorg.springframework.web.util.HtmlUtils.htmlEscape(…) method.
Note: There is similar classe in Apache Commons :org.apache.commons.lang.StringEscapeUtils.escapeHtml(…) - the SQL injection characters (‘, “, …) via the Apache Commons classeorg.apache.commons.lang.StringEscapeUtils.escapeSql(…)
01 | package com.huo.filter; |
02 |
03 | import java.io.IOException; |
04 |
05 | import javax.servlet.Filter; |
06 | import javax.servlet.FilterChain; |
07 | import javax.servlet.FilterConfig; |
08 | import javax.servlet.ServletException; |
09 | import javax.servlet.ServletRequest; |
10 | import javax.servlet.ServletReponse; |
11 | import javax.servlet.http.HttpServletRequest; |
12 |
13 | public class RequestWrappingFilter implements Filter{ |
14 |
15 | public void doFilter(ServletRequest req, ServletReponse res, FilterChain chain) throws IOException, ServletException{ |
16 | chain.doFilter( new MyHttpRequestWrapper(req), res); |
17 | } |
18 |
19 | public void init(FilterConfig config) throws ServletException{ |
20 | } |
21 |
22 | public void destroy() throws ServletException{ |
23 | } |
24 | } |
01 | package com.huo.filter; |
02 |
03 | import java.util.HashMap; |
04 | import java.util.Map; |
05 |
06 | import javax.servlet.ServletException; |
07 | import javax.servlet.http.HttpServletRequest; |
08 | import javax.servlet.http.HttpServletRequestWrapper; |
09 |
10 | import org.apache.commons.lang.StringEscapeUtils; |
11 |
12 | public class MyHttpRequestWrapper implements HttpServletRequestWrapper{ |
13 | private Map<String, String[]> escapedParametersValuesMap = new HashMap<String, String[]>(); |
14 |
15 | public MyHttpRequestWrapper(HttpServletRequest req){ |
16 | super (req); |
17 | } |
18 |
19 | @Override |
20 | public String getParameter(String name){ |
21 | String[] escapedParameterValues = escapedParametersValuesMap.get(name); |
22 | String escapedParameterValue = null ; |
23 | if (escapedParameterValues!= null ){ |
24 | escapedParameterValue = escapedParameterValues[ 0 ]; |
25 | } else { |
26 | String parameterValue = super .getParameter(name); |
27 |
28 | // HTML transformation characters |
29 | escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue); |
30 | |
31 | // SQL injection characters |
32 | escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue); |
33 | |
34 | escapedParametersValuesMap.put(name, new String[]{escapedParameterValue}); |
35 | } //end-else |
36 | |
37 | return escapedParameterValue; |
38 | } |
39 |
40 | @Override |
41 | public String[] getParameterValues(String name){ |
42 | String[] escapedParameterValues = escapedParametersValuesMap.get(name); |
43 | if (escapedParameterValues== null ){ |
44 | String[] parametersValues = super .getParameterValues(name); |
45 | escapedParameterValue = new String[parametersValues.length]; |
46 |
47 | // |
48 | for ( int i= 0 ; i<parametersValues.length; i++){ |
49 | String parameterValue = parametersValues[i]; |
50 | String escapedParameterValue = parameterValue; |
51 | |
52 | // HTML transformation characters |
53 | escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue); |
54 | |
55 | // SQL injection characters |
56 | escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue); |
57 | |
58 | escapedParameterValues[i] = escapedParameterValue; |
59 | } //end-for |
60 | |
61 | escapedParametersValuesMap.put(name, escapedParameterValues); |
62 | } //end-else |
63 | |
64 | return escapedParameterValues; |
65 | } |
66 | } |