SQL 인젝션이란?
내가 SQL 주입으로 이해한 것은 일부 사람들이 악의적인 매개 변수를 입력하여 백그라운드에서 이 SQL을 실행하게 한 다음 데이터를 얻거나 데이터베이스를 파괴하려는 목적을 달성할 수 있다는 것입니다!
간단한 쿼리 예를 제공하기 위해 백그라운드 SQL이 연결됩니다. 테스트에서 *를 선택하고 여기서 name='+parameter transfer+'; 첫 페이지에 이름을 입력해야 하면 해커가 다음을 입력할 수 있습니다. ';DROP TABLE Test;-- 다음 SQL 코드를 무시하지 마세요.
select * from Test where name=' ';DROP TABLE Test;--'; 이는 정확하고 SQL에서 실행 가능하지만 실행 후에는 전체 테스트 테이블이 삭제되고 웹사이트가 다운됩니다!
가장 좋은 해결책
가장 좋은 해결책은 스플라이싱 SQL을 작성하는 것이 아니라 매개변수화된 SQL을 사용하는 것이며, 이는 새 프로젝트에 권장됩니다. 여기에는 소개가 없으며 관심있는 친구들이 스스로 검색할 수 있습니다. 이 기사에서 소개된 방법은 이전 프로젝트에 적합합니다. 즉, 매개변수화된 SQL을 사용하여 개발된 프로그램이 없습니다.
필터 기능을 사용하여
일부 위험한 SQL 키워드를 필터링하고, 일반적으로 코드를 작성할 때 전혀 나타나지 않는 문자인 주석 백분율 기호와 세미콜론을 필터링합니다. , SQL 실행이 최대한 안전한지 확인하기 위해 코드는 다음과 같습니다.
public class SqlFilter { public static void Filter() { string fileter_sql = "execute,exec,select,insert,update,delete,create,drop,alter,exists,table,sysobjects,truncate,union,and,order,xor,or,mid,cast,where,asc,desc,xp_cmdshell,join,declare,nvarchar,varchar,char,sp_oacreate,wscript.shell,xp_regwrite,',%,;,--"; try { // -----------------------防 Post 注入----------------------- if (HttpContext.Current.Request.Form != null) { PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); //把 Form 属性改为可读写 isreadonly.SetValue(HttpContext.Current.Request.Form, false, null); for (int k = 0; k < System.Web.HttpContext.Current.Request.Form.Count; k++) { string getsqlkey = HttpContext.Current.Request.Form.Keys[k]; string sqlstr = HttpContext.Current.Request.Form[getsqlkey]; string[] replace_sqls = fileter_sql.Split(','); foreach (string replace_sql in replace_sqls) { sqlstr = Regex.Replace(sqlstr, replace_sql, "", RegexOptions.IgnoreCase); } HttpContext.Current.Request.Form[getsqlkey] = sqlstr; } } // -----------------------防 GET 注入----------------------- if (HttpContext.Current.Request.QueryString != null) { PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); //把 QueryString 属性改为可读写 isreadonly.SetValue(HttpContext.Current.Request.QueryString, false, null); for (int k = 0; k < System.Web.HttpContext.Current.Request.QueryString.Count; k++) { string getsqlkey = HttpContext.Current.Request.QueryString.Keys[k]; string sqlstr = HttpContext.Current.Request.QueryString[getsqlkey]; string[] replace_sqls = fileter_sql.Split(','); foreach (string replace_sql in replace_sqls) { sqlstr = Regex.Replace(sqlstr, replace_sql, "", RegexOptions.IgnoreCase); } HttpContext.Current.Request.QueryString[getsqlkey] = sqlstr; } } // -----------------------防 Cookies 注入----------------------- if (HttpContext.Current.Request.Cookies != null) { PropertyInfo isreadonly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); //把 Cookies 属性改为可读写 isreadonly.SetValue(HttpContext.Current.Request.Cookies, false, null); for (int k = 0; k < System.Web.HttpContext.Current.Request.Cookies.Count; k++) { string getsqlkey = HttpContext.Current.Request.Cookies.Keys[k]; string sqlstr = HttpContext.Current.Request.Cookies[getsqlkey].Value; string[] replace_sqls = fileter_sql.Split(','); foreach (string replace_sql in replace_sqls) { sqlstr = Regex.Replace(sqlstr, replace_sql, "", RegexOptions.IgnoreCase); } HttpContext.Current.Request.Cookies[getsqlkey].Value = sqlstr; } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
SQL 주입을 방지하기 위한 추가 ASP.NET 필터링 클래스 SqlFilter에 대해서는 PHP 중국어 웹사이트에 주의하세요. 관련 기사!