WebApi용 SQL 주입 필터
가장 효과적인 SQL 주입 방지 방법은 데이터베이스를 호출할 때 매개 변수화된 조회를 사용하는 것이다.하지만 오래된 웹에이피 프로젝트를 맡는다면 데이터베이스 접근층의 코드를 많이 바꾸지 않으려면 어떻게 해야 하는가.
나의 해결 방안은 필터를 추가하는 것이다.
먼저 필터 방법을 쓰고 코드를 올리다
using System;
using System.Collections.Generic;
using System.Web;
namespace Test
{
///
/// SQL
///
public class AntiSqlInject
{
public static AntiSqlInject Instance = new AntiSqlInject();
///
///
///
static AntiSqlInject()
{
SqlKeywordsArray.AddRange(SqlSeparatKeywords.Split('|'));
SqlKeywordsArray.AddRange(Array.ConvertAll(SqlCommandKeywords.Split('|'), h => h + " "));
SqlKeywordsArray.AddRange(Array.ConvertAll(SqlCommandKeywords.Split('|'), h => " " + h));
}
private const string SqlCommandKeywords = "and|exec|execute|insert|select|delete|update|count|chr|mid|master|" +
"char|declare|sitename|net user|xp_cmdshell|or|create|drop|table|from|grant|use|group_concat|column_name|" +
"information_schema.columns|table_schema|union|where|select|delete|update|orderhaving|having|by|count|*|truncate|like";
private const string SqlSeparatKeywords = "'|;|--|\'|\"|/*|%|#";
private static readonly List SqlKeywordsArray = new List();
///
///
///
///
///
public bool IsSafetySql(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return true;
}
input = HttpUtility.UrlDecode(input).ToLower();
foreach (var sqlKeyword in SqlKeywordsArray)
{
if (input.IndexOf(sqlKeyword, StringComparison.Ordinal) >= 0)
{
return false;
}
}
return true;
}
///
///
///
///
///
public string GetSafetySql(string input)
{
if (string.IsNullOrEmpty(input))
{
return string.Empty;
}
if (IsSafetySql(input)) { return input; }
input = HttpUtility.UrlDecode(input).ToLower();
foreach (var sqlKeyword in SqlKeywordsArray)
{
if (input.IndexOf(sqlKeyword, StringComparison.Ordinal) >= 0)
{
input = input.Replace(sqlKeyword, string.Empty);
}
}
return input;
}
}
}
그 다음은 필터, 코드부터
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace Test
{
///
///
///
///
/// SQL
///
public class AntiSqlInjectFilter : ActionFilterAttribute
{
///
///
///
///
public override void OnActionExecuting(HttpActionContext filterContext)
{
base.OnActionExecuting(filterContext);
var actionParameters = filterContext.ActionDescriptor.GetParameters();
var actionArguments = filterContext.ActionArguments;
foreach (var p in actionParameters)
{
var value = filterContext.ActionArguments[p.ParameterName];
var pType = p.ParameterType;
if (value == null)
{
continue;
}
// ,
if (!pType.IsClass) continue;
if (value is string)
{
// string
filterContext.ActionArguments[p.ParameterName] = AntiSqlInject.Instance.GetSafetySql(value.ToString());
}
else
{
// class, class ,string
var properties = pType.GetProperties();
foreach (var pp in properties)
{
var temp = pp.GetValue(value);
if (temp == null)
{
continue;
}
pp.SetValue(value, temp is string ? AntiSqlInject.Instance.GetSafetySql(temp.ToString()) : temp);
}
}
}
}
}
}
필터를 추가하여 ActionFilterAttribute를 계승하고 OnactionExecuting 방법을 다시 쓰고 인삼을 가져오며 인삼의string 형식의 모든 데이터를 필터합니다.두 가지 상황, 하나는 매개 변수가string 유형이고, 다른 하나는 클래스의 속성이다.필터 끝났어.
필터는 두 가지 사용 방식이 있는데, 하나는 구체적인 방법에 첨가하는 것이다
[HttpPut,Route("api/editSomething")]
[AntiSqlInjectFilter]
public async Task EditSomeThingAsync([FromBody]SomeThing model)
{
var response = await SomeThingBusiness.Editsync(model);
return response;
}
하나는 WebApiConfig에서 전역 구성입니다.cs 파일의 Register 메서드에 필터 추가
using System.Web.Http;
namespace Test
{
///
/// WebApi
///
public static class WebApiConfig
{
///
///
///
///
public static void Register(HttpConfiguration config)
{
// Web API
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// SQL
config.Filters.Add(new AntiSqlInjectFilter());
}
}
}
테스트가 유효하다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.