ASP.NET Core中如何利用Csp标头对抗Xss攻击

extremecold 2019-09-07

å容å®å¨ç­ç¥ï¼CSPï¼æ¯ä¸ä¸ªå¢å çå®å¨å±ï¼å¯å¸®å©æ£æµåç¼è§£æäºç±»åçæ»å»ï¼åæ¬è·¨ç«ç¹èæ¬ï¼XSSï¼åæ°æ®æ³¨å¥æ»å»ãè¿äºæ»å»ç¨äºä»æ°æ®çªåå°ç«ç¹ç ´åææ¶æ软件ååçææå容ï¼æ·±å¥CSPï¼

ç®èè¨ä¹ï¼CSPæ¯ç½é¡µæ§å¶å许å è½½åªäºèµæºçä¸ç§æ¹å¼ãä¾å¦ï¼é¡µé¢å¯ä»¥æ¾å¼å£°æå许ä»ä¸­å è½½JavaScriptï¼CSSåå¾åèµæºãè¿æå©äºé²æ­¢è·¨ç«ç¹èæ¬ï¼XSSï¼æ»å»ç­é®é¢ã

å®ä¹å¯ç¨äºéå¶åè®®ï¼ä¾å¦éå¶éè¿HTTPSå è½½çå容ãCSPéè¿ Content-Security-Policy HTTPååºä¸­çæ å¤´å®ç°ã

å¯ç¨CSP,æ¨éè¦éç½®Webæå¡å¨ä»¥è¿åContent-Security-Policy HTTPæ å¤´ãé£ä¹å¨è¿ç¯æ章中ï¼æ们å°è¦å°è¯å°CSPæ·»å å°ASP.NET Coreåºç¨ç¨åºä¸­ã

app.Use(async (ctx, next) =>
  {
  ctx.Response.Headers.Add("Content-Security-Policy",
    "default-src 'self'; report-uri /cspreport");
  await next();
  });

å¨Home/Index中å¼å¥cdnæ件ï¼ç¶åæ们å¯å¨é¡¹ç®ï¼ççä¼åçä»ä¹ï¼

ASP.NET Core中如何利用Csp标头对抗Xss攻击

è¿è¡å¹¶è§å¯é误ãå è½½é¡µé¢æ¶ï¼æµè§å¨æç»ä»è¿ç¨æºå è½½ã

ASP.NET Core中如何利用Csp标头对抗Xss攻击 

æ以æ们å¯ä»¥ç»ç»CSPæ¥æ§å¶æ们çç½ååï¼å¨éç½®å½ä¸­éè¦å¡«åæ¥æºä»¥åå容ï¼ä»¥ä¸æ¯å¸¸ç¨éå¶çé项ã

æ¥æºï¼

*: å许任ä½ç½åã
âself': å许ææä¾é¡µé¢çæ¥æºã请注æï¼åå¼å·æ¯å¿éçã
ânone': ä¸å许任ä½æ¥æºã请注æï¼åå¼å·æ¯å¿éçã
Host: å许æå®çäºèç½ä¸»æºï¼æå称æIPå°åï¼ãéé符ï¼æå·å­ç¬¦ï¼å¯ç¨äºåæ¬ææå­åï¼ä¾å¦httpï¼//*.foo.com
âunsafe-line': å许åèèæ¬
ânonce-[base64-value]': å许å·æç¹å®nonceçåèèæ¬ï¼ä½¿ç¨ä¸æ¬¡çæ°å­ï¼ã对äºæ¯ä¸ªHTTP请æ±/ååºï¼åºè¯¥å¯¹nonceè¿è¡å å¯åå¯ä¸ã

 æ令ï¼

script-srcï¼å®ä¹ææçJavaScriptæº
style-srcï¼å®ä¹æ ·å¼è¡¨çæææ¥æº
img-srcï¼å®ä¹ææçå¾åæº
connect-srcï¼å®ä¹å¯ä»¥è¿è¡AJAXè°ç¨çæææº
font-srcï¼å®ä¹ææçå­ä½æ¥æº
object-srcï¼å®ä¹<object>ï¼<embed>å<applet>åç´ çæææº
media-srcï¼å®ä¹ææçé³é¢åè§é¢æº
form-actionï¼å®ä¹å¯ç¨ä½HTML <form>æä½çæææºã
default-srcï¼æå®å è½½å容çé»è®¤ç­ç¥

æ们å¯ä»¥å¨å¯éç¨ç中é´ä»¶ä¸­å°è£æ建åæ·»å CSP头ã以ä¸æ¯ä¸ä¸ªè®©æ¨å¥é¨ç示ä¾ãä½ å¯ä»¥æ ¹æ®éè¦æ©å±å®ãé¦åï¼å建ä¸ä¸ªç¨äºä¿å­æºçç±»ã

public class CspOptions
 {
  public List<string> Defaults { get; set; } = new List<string>();
  public List<string> Scripts { get; set; } = new List<string>();
  public List<string> Styles { get; set; } = new List<string>();
  public List<string> Images { get; set; } = new List<string>();
  public List<string> Fonts { get; set; } = new List<string>();
  public List<string> Media { get; set; } = new List<string>();
 }

å¼åä¸ä¸ªä¸­é´ä»¶ä¸å®æ¯éè¦ä¸ä¸ªæé å¨çï¼è¿å°ç¨äº.net core ç注å¥å°è¿è¡ç¯å¢ä¸­ã

public sealed class CspOptionsBuilder 
 { 
  private readonly CspOptions options = new CspOptions(); 
  
  internal CspOptionsBuilder() { } 
 
  public CspDirectiveBuilder Defaults { get; set; } = new CspDirectiveBuilder(); 
  public CspDirectiveBuilder Scripts { get; set; } = new CspDirectiveBuilder(); 
  public CspDirectiveBuilder Styles { get; set; } = new CspDirectiveBuilder(); 
  public CspDirectiveBuilder Images { get; set; } = new CspDirectiveBuilder(); 
  public CspDirectiveBuilder Fonts { get; set; } = new CspDirectiveBuilder(); 
  public CspDirectiveBuilder Media { get; set; } = new CspDirectiveBuilder(); 
 
  internal CspOptions Build() 
  { 
   this.options.Defaults = this.Defaults.Sources; 
   this.options.Scripts = this.Scripts.Sources; 
   this.options.Styles = this.Styles.Sources; 
   this.options.Images = this.Images.Sources; 
   this.options.Fonts = this.Fonts.Sources; 
   this.options.Media = this.Media.Sources; 
   return this.options; 
  } 
 } 
 
 public sealed class CspDirectiveBuilder 
 { 
  internal CspDirectiveBuilder() { } 
 
  internal List<string> Sources { get; set; } = new List<string>(); 
 
  public CspDirectiveBuilder AllowSelf() => Allow("'self'"); 
  public CspDirectiveBuilder AllowNone() => Allow("none"); 
  public CspDirectiveBuilder AllowAny() => Allow("*"); 
 
  public CspDirectiveBuilder Allow(string source) 
  { 
   this.Sources.Add(source); 
   return this; 
  } 
 }

好äºï¼æ们å建ä¸ä¸ªä¸­é´ä»¶ã

namespace XSSDefenses.XSSDefenses.MiddlerWare
{
 public sealed class CspOptionMiddlerWare
 {
  private const string HEADER = "Content-Security-Policy";
  private readonly RequestDelegate next;
  private readonly CspOptions options;

  public CspOptionMiddlerWare(
   RequestDelegate next, CspOptions options)
  {
   this.next = next;
   this.options = options;
  }

  public async Task Invoke(HttpContext context)
  {
   context.Response.Headers.Add(HEADER, GetHeaderValue());
   await this.next(context);
  }

  private string GetHeaderValue()
  {
   var value = "";
   value += GetDirective("default-src", this.options.Defaults);
   value += GetDirective("script-src", this.options.Scripts);
   value += GetDirective("style-src", this.options.Styles);
   value += GetDirective("img-src", this.options.Images);
   value += GetDirective("font-src", this.options.Fonts);
   value += GetDirective("media-src", this.options.Media);
   return value;
  }
  private string GetDirective(string directive, List<string> sources)
   => sources.Count > 0 ? $"{directive} {string.Join(" ", sources)}; " : "";
 }
}

以å设置å®çæ©å±æ¹æ³ã

namespace XSSDefenses.XSSDefenses.Extensions
{
 public static class CspMiddlewareExtensions
 {
  public static IApplicationBuilder UseCsp(
    this IApplicationBuilder app, Action<CspOptionsBuilder> builder)
  {
   var newBuilder = new CspOptionsBuilder();
   builder(newBuilder);
 
   var options = newBuilder.Build();
   return app.UseMiddleware<CspOptionMiddlerWare>(options);
  }
 }
}

æ们ç°å¨å¯ä»¥å¨Startup类中é置中é´ä»¶ã

app.UseCsp(builder =>
   {
    builder.Styles.AllowSelf()
    .Allow(@"https://ajax.aspnetcdn.com/");
   });

å¯å¨åç°ï¼è§å¯ç½ç»èµæºãæµè§å¨å·²ç»å许æ¬å°åè¿ç¨èµæºã

ASP.NET Core中如何利用Csp标头对抗Xss攻击

æ»ç»

以ä¸å°±æ¯è¿ç¯æç« çå¨é¨å容äºï¼å¸ææ¬æçå容对大家ç学习æèå·¥ä½å·æä¸å®çåè学习价å¼ï¼è°¢è°¢å¤§å®¶å¯¹èæ¬ä¹å®¶çæ¯æã

相关推荐