日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dotnet Core Public API的安全实践

發(fā)布時(shí)間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dotnet Core Public API的安全实践 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

公開API的安全,其實(shí)更重要。

?

一、API的安全

作為一個(gè)Dotnet Core的老司機(jī),寫API時(shí),能兼顧到API的安全,這是一種優(yōu)雅。

?

通常,我們會(huì)用認(rèn)證來保證API的安全,無敵的Authorize能解決我們很多的問題。

但是,總有一些場合,我們沒辦法用Authorize,而只能用匿名或不加驗(yàn)證的方式來訪問。比方電商中查詢SKU的列表并在前端展示,通常這個(gè)無關(guān)用戶和權(quán)限,在完成API的時(shí)候,我們也不會(huì)加入認(rèn)證Authorize。

這種情況下,如果直接寫,不加入安全級(jí)別,這樣的體系結(jié)構(gòu)是有可能成為可供利用的安全漏洞的。

?

Dotnet Core框架已經(jīng)提供了一些常見漏洞的解決方法,包括:

  • 跨站點(diǎn)腳本

  • SQL注入

  • 跨站點(diǎn)請(qǐng)求偽造(CSRF)

  • 重定向

等等。

但是,我們還需要更進(jìn)一步,還需要照顧到以下常見的攻擊:

  • 拒絕服務(wù)(DOS)

  • 分布式拒絕服務(wù)(DDOS)

  • 批量API調(diào)用

  • 探測(cè)響應(yīng)

  • 數(shù)據(jù)抓取

這部分內(nèi)容,需要我們自己實(shí)現(xiàn)。當(dāng)然,這部分內(nèi)容的實(shí)現(xiàn),也可以從Web Server上進(jìn)行設(shè)置。

本文討論的,是代碼的實(shí)現(xiàn)。

二、相關(guān)代碼

今天偷個(gè)懶,不講原理,以分享代碼為主。

2.1 基于IP的客戶端請(qǐng)求限制

通過限制客戶端在指定的時(shí)間范圍內(nèi)的請(qǐng)求數(shù)量,防止惡意bot攻擊。

代碼中,我建立了一個(gè)基于IP的請(qǐng)求限制過濾器。

注意:有多個(gè)客戶端位于同一個(gè)IP地址的情況,這個(gè)情況在這個(gè)代碼中沒有考慮。如果您希望實(shí)現(xiàn)這一點(diǎn),可以把幾種方式結(jié)合起來使用。

以下是代碼:

[AttributeUsage(AttributeTargets.Method)] public?class?RequestLimitAttribute?:?ActionFilterAttribute {public?string?Name?{?get;?}public?int?NoOfRequest?{?get;?set;?}public?int?Seconds?{?get;?set;?}private?static?MemoryCache?Cache?{?get;?}?=?new?MemoryCache(new?MemoryCacheOptions());public?RequestLimitAttribute(string?name,?int?noOfRequest?=?5,?int?seconds?=?10){Name?=?name;NoOfRequest?=?noOfRequest;Seconds?=?seconds;}public?override?void?OnActionExecuting(ActionExecutingContext?context){var?ipAddress?=?context.HttpContext.Request.HttpContext.Connection.RemoteIpAddress;var?memoryCacheKey?=?$"{Name}-{ipAddress}";Cache.TryGetValue(memoryCacheKey,?out?int?prevReqCount);if?(prevReqCount?>=?NoOfRequest){context.Result?=?new?ContentResult{Content?=?$"Request?limit?is?exceeded.?Try?again?in?{Seconds}?seconds.",};context.HttpContext.Response.StatusCode?=?(int)HttpStatusCode.TooManyRequests;}else{var?cacheEntryOptions?=?new?MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(Seconds));Cache.Set(memoryCacheKey,?(prevReqCount?+?1),?cacheEntryOptions);}} }

使用時(shí),只要在需要的API前加屬性即可:

[HttpGet] [RequestLimit("DataGet",?5,?30)] public?IEnumerable<WeatherForecast>?Get() {... }

2.2 引用頭檢查

對(duì)API請(qǐng)求的請(qǐng)求引用頭進(jìn)行檢查,可以防止API濫用,以及跨站點(diǎn)請(qǐng)求偽造(CSRF)攻擊。

同樣,也是采用自定義屬性的方式。

public?class?ValidateReferrerAttribute?:?ActionFilterAttribute {private?IConfiguration?_configuration;public?override?void?OnActionExecuting(ActionExecutingContext?context){_configuration?=?(IConfiguration)context.HttpContext.RequestServices.GetService(typeof(IConfiguration));base.OnActionExecuting(context);if?(!IsValidRequest(context.HttpContext.Request)){context.Result?=?new?ContentResult{Content?=?$"Invalid?referer?header",};context.HttpContext.Response.StatusCode?=?(int)HttpStatusCode.ExpectationFailed;}}private?bool?IsValidRequest(HttpRequest?request){string?referrerURL?=?"";if?(request.Headers.ContainsKey("Referer")){referrerURL?=?request.Headers["Referer"];}if?(string.IsNullOrWhiteSpace(referrerURL))?return?true;var?allowedUrls?=?_configuration.GetSection("CorsOrigin").Get<string[]>()?.Select(url?=>?new?Uri(url).Authority).ToList();bool?isValidClient?=?allowedUrls.Contains(new?Uri(referrerURL).Authority);return?isValidClient;} }

這里我用了一個(gè)配置,在appsetting.json中:

{"CorsOrigin":?["https://test.com",?"http://test1.cn:8080"] }

CorsOrigin參數(shù)中加入允許引用的來源域名:端口列表。

使用時(shí),在需要的API前加屬性:

[HttpGet] [ValidateReferrer] public?IEnumerable<WeatherForecast>?Get() {... }

2.3 DDOS攻擊檢查

DDOS攻擊在網(wǎng)上很常見,這種攻擊簡單有效,可以讓一個(gè)網(wǎng)站瞬間開始并長時(shí)間無法響應(yīng)。通常來說,網(wǎng)站可以通過多種節(jié)流方法來避免這種情況。

下面我們換一種方式,用中間件MiddleWare來限制特定客戶端IP的請(qǐng)求數(shù)量。

public?class?DosAttackMiddleware {private?static?Dictionary<string,?short>?_IpAdresses?=?new?Dictionary<string,?short>();private?static?Stack<string>?_Banned?=?new?Stack<string>();private?static?Timer?_Timer?=?CreateTimer();private?static?Timer?_BannedTimer?=?CreateBanningTimer();private?const?int?BANNED_REQUESTS?=?10;private?const?int?REDUCTION_INTERVAL?=?1000;?//?1?second????private?const?int?RELEASE_INTERVAL?=?5?*?60?*?1000;?//?5?minutes????private?RequestDelegate?_next;public?DosAttackMiddleware(RequestDelegate?next){_next?=?next;}public?async?Task?InvokeAsync(HttpContext?httpContext){string?ip?=?httpContext.Connection.RemoteIpAddress.ToString();if?(_Banned.Contains(ip)){httpContext.Response.StatusCode?=?(int)HttpStatusCode.Forbidden;}CheckIpAddress(ip);await?_next(httpContext);}private?static?void?CheckIpAddress(string?ip){if?(!_IpAdresses.ContainsKey(ip)){_IpAdresses[ip]?=?1;}else?if?(_IpAdresses[ip]?==?BANNED_REQUESTS){_Banned.Push(ip);_IpAdresses.Remove(ip);}else{_IpAdresses[ip]++;}}private?static?Timer?CreateTimer(){Timer?timer?=?GetTimer(REDUCTION_INTERVAL);timer.Elapsed?+=?new?ElapsedEventHandler(TimerElapsed);return?timer;}private?static?Timer?CreateBanningTimer(){Timer?timer?=?GetTimer(RELEASE_INTERVAL);timer.Elapsed?+=?delegate?{if?(_Banned.Any())?_Banned.Pop();};return?timer;}private?static?Timer?GetTimer(int?interval){Timer?timer?=?new?Timer();timer.Interval?=?interval;timer.Start();return?timer;}private?static?void?TimerElapsed(object?sender,?ElapsedEventArgs?e){foreach?(string?key?in?_IpAdresses.Keys.ToList()){_IpAdresses[key]--;if?(_IpAdresses[key]?==?0)?_IpAdresses.Remove(key);}} }

代碼中設(shè)置:1秒(1000ms)中有超過10次訪問時(shí),對(duì)應(yīng)的IP會(huì)被禁用5分鐘。

使用時(shí),在Startup.cs中直接加載中間件:

public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {...app.UseMiddleware<DosAttackMiddleware>();... }

三、結(jié)尾的話

以上代碼僅為拋磚引玉之用。

公開的API,未經(jīng)驗(yàn)證的API,在生產(chǎn)環(huán)境會(huì)因?yàn)榉N種原因被攻擊。這幾天公司的系統(tǒng)就因?yàn)檫@個(gè)出了大事。

所以,寫API的時(shí)候,要充分考慮到這些網(wǎng)絡(luò)攻擊的可能性,通過正確的處理,來防止來自網(wǎng)絡(luò)的攻擊。

這是一份責(zé)任,也是一個(gè)理念。

與大家共勉!

?

(全文完)

?

本文的代碼,我已經(jīng)傳到Github上,位置在:https://github.com/humornif/Demo-Code/tree/master/0021/demo

喜歡就來個(gè)三連,讓更多人因你而受益

總結(jié)

以上是生活随笔為你收集整理的Dotnet Core Public API的安全实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。