2015-04-29 17 views
10

Utworzono aplikację formularza sieci Web ASP.Net przy użyciu programu Visual Studio 2013 i używam aplikacji Dot Net Frame Work 4.5 i chcę się upewnić, że witryna jest bezpieczna od żądania Cross-Site Fałszerstwo (CSRF), znalazłem wiele artykułów mówiących o tym, jak ta funkcja jest realizowana na MVC apps, ale bardzo niewiele mówi o formach internetowych, na this StackOverflow question jeden komentarz jest stwierdzając, żezapobieganie atakom typu "cross-site request for forgery" (csrf) w formularzach WWW asp.net

"To jest stare pytanie, ale najnowszy szablon ASP.NET do tworzenia formularzy internetowych zawiera kod anty-CSRF zapakowany na stronie głównej . Jeśli nie masz szablonów, oto kod generuje: ... "

ale moja strona wzorcowa nie zawiera kodu, o którym wspomniał w swojej odpowiedzi, więc czy ktoś może mi pomóc? czy to naprawdę zrealizowane? jeśli nie, proszę doradzić, jaki jest najlepszy sposób na zrobienie tego?

+0

możliwy duplikat [Zapobiegaj fałszerstwom żądań między witrynami] (http: // stackoverflow.com/questions/24675779/prevent-cross-site-request-falsyfikat) – SilverlightFox

+0

@SilverlightFox, Hope not;) –

Odpowiedz

10

ViewStateUserKey & Pokój Prześlij Cookie

Wychodząc z Visual Studio 2012, Microsoft dodał wbudowaną ochronę CSRF do nowych projektów aplikacji Web Forms. Aby wykorzystać ten kod, dodaj nową aplikację ASP .NET Web Forms do swojego rozwiązania i wyświetl kod Site.Master za stroną. To rozwiązanie zastosuje ochronę CSRF do wszystkich stron zawartości, które dziedziczą ze strony Site.Master.

następujące wymagania muszą być spełnione, aby to rozwiązanie działa:

Wszystkie formularze wprowadzania zmian danych należy użyć strony Site.Master. Wszystkie żądania modyfikacji danych muszą korzystać z ViewState. Strona internetowa musi być wolna od wszelkich luk XSS (Cross-Site Scripting). Zobacz, jak naprawić Cross-Site Scripting (XSS) przy użyciu Microsoft .Net Web Protection Library, aby uzyskać szczegółowe informacje.

public partial class SiteMaster : MasterPage 
{ 
    private const string AntiXsrfTokenKey = "__AntiXsrfToken"; 
    private const string AntiXsrfUserNameKey = "__AntiXsrfUserName"; 
    private string _antiXsrfTokenValue; 

    protected void Page_Init(object sender, EventArgs e) 
    { 
    //First, check for the existence of the Anti-XSS cookie 
    var requestCookie = Request.Cookies[AntiXsrfTokenKey]; 
    Guid requestCookieGuidValue; 

    //If the CSRF cookie is found, parse the token from the cookie. 
    //Then, set the global page variable and view state user 
    //key. The global variable will be used to validate that it matches 
    //in the view state form field in the Page.PreLoad method. 
    if (requestCookie != null 
     && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue)) 
    { 
     //Set the global token variable so the cookie value can be 
     //validated against the value in the view state form field in 
     //the Page.PreLoad method. 
     _antiXsrfTokenValue = requestCookie.Value; 

     //Set the view state user key, which will be validated by the 
     //framework during each request 
     Page.ViewStateUserKey = _antiXsrfTokenValue; 
    } 
    //If the CSRF cookie is not found, then this is a new session. 
    else 
    { 
     //Generate a new Anti-XSRF token 
     _antiXsrfTokenValue = Guid.NewGuid().ToString("N"); 

     //Set the view state user key, which will be validated by the 
     //framework during each request 
     Page.ViewStateUserKey = _antiXsrfTokenValue; 

     //Create the non-persistent CSRF cookie 
     var responseCookie = new HttpCookie(AntiXsrfTokenKey) 
     { 
     //Set the HttpOnly property to prevent the cookie from 
     //being accessed by client side script 
     HttpOnly = true, 

     //Add the Anti-XSRF token to the cookie value 
     Value = _antiXsrfTokenValue 
     }; 

     //If we are using SSL, the cookie should be set to secure to 
     //prevent it from being sent over HTTP connections 
     if (FormsAuthentication.RequireSSL && 
      Request.IsSecureConnection) 
     { 
     responseCookie.Secure = true; 
     } 

     //Add the CSRF cookie to the response 
     Response.Cookies.Set(responseCookie); 
    } 

    Page.PreLoad += master_Page_PreLoad; 
    } 

    protected void master_Page_PreLoad(object sender, EventArgs e) 
    { 
    //During the initial page load, add the Anti-XSRF token and user 
    //name to the ViewState 
    if (!IsPostBack) 
    { 
     //Set Anti-XSRF token 
     ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; 

     //If a user name is assigned, set the user name 
     ViewState[AntiXsrfUserNameKey] = 
      Context.User.Identity.Name ?? String.Empty; 
    } 
    //During all subsequent post backs to the page, the token value from 
    //the cookie should be validated against the token in the view state 
    //form field. Additionally user name should be compared to the 
    //authenticated users name 
    else 
    { 
     //Validate the Anti-XSRF token 
     if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue 
      || (string)ViewState[AntiXsrfUserNameKey] != 
       (Context.User.Identity.Name ?? String.Empty)) 
     { 
     throw new InvalidOperationException("Validation of " + 
          "Anti-XSRF token failed."); 
     } 
    } 
    } 
} 
+0

Używam VS2017 i nie widzę tego kodu w Site.Master.cs (zupełnie nowy projekt aplikacji formularzy internetowych). – joym8

6

Po utworzeniu nowego projektu "Formularz sieciowy" w VS 2013, plik site.master.cs automatycznie umieści kod XSRF/CSRF w sekcji Page_Init klasy. Jeśli nadal nie otrzymasz wygenerowanego kodu, możesz ręcznie kodem Copy + Paste. Jeśli używasz C#, a następnie użyj poniżej: -

private const string AntiXsrfTokenKey = "__AntiXsrfToken"; 
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName"; 
private string _antiXsrfTokenValue; 

protected void Page_Init(object sender, EventArgs e) 
    { 
     // The code below helps to protect against XSRF attacks 
     var requestCookie = Request.Cookies[AntiXsrfTokenKey]; 
     Guid requestCookieGuidValue; 
     if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue)) 
     { 
      // Use the Anti-XSRF token from the cookie 
      _antiXsrfTokenValue = requestCookie.Value; 
      Page.ViewStateUserKey = _antiXsrfTokenValue; 
     } 
     else 
     { 
      // Generate a new Anti-XSRF token and save to the cookie 
      _antiXsrfTokenValue = Guid.NewGuid().ToString("N"); 
      Page.ViewStateUserKey = _antiXsrfTokenValue; 

      var responseCookie = new HttpCookie(AntiXsrfTokenKey) 
      { 
       HttpOnly = true, 
       Value = _antiXsrfTokenValue 
      }; 
      if (FormsAuthentication.RequireSSL && Request.IsSecureConnection) 
      { 
       responseCookie.Secure = true; 
      } 
      Response.Cookies.Set(responseCookie); 
     } 

     Page.PreLoad += master_Page_PreLoad; 
    } 

    protected void master_Page_PreLoad(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      // Set Anti-XSRF token 
      ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey; 
      ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty; 
     } 
     else 
     { 
      // Validate the Anti-XSRF token 
      if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue 
       || (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty)) 
      { 
       throw new InvalidOperationException("Validation of Anti-XSRF token failed."); 
      } 
     } 
    } 
+0

Tak, używam C#, i próbowałem skopiować i minąć tę funkcję, ale wydaje się, że ma wiele błędów. Czy jesteś pewien, że jest to wygenerowany automatycznie kod? –

+0

nie rozpoznaje: AntiXsrfTokenKey w Request.Cookies [AntiXsrfTokenKey]; , a także nie rozpoznaje tych zmiennych, a także _antiXsrfTokenValue, master_Page_PreLoad –

+0

@NadaNaeem Zawarłem brakujące stałe. –

15

Możesz wypróbować następujące rzeczy. W formularzu internetowym dodaj:

<%= System.Web.Helpers.AntiForgery.GetHtml() %> 

Spowoduje to dodanie ukrytego pola i pliku cookie. Więc jeśli wypełnić pewne dane formularzy i umieścić go z powrotem do serwera trzeba prostą kontrolę:

protected void Page_Load(object sender, EventArgs e) 
{ 
if (IsPostBack) 
AntiForgery.Validate(); 
} 

AntiForgery.Validate(); zgłasza wyjątek, jeśli kontrola anty XSFR zawiedzie.

+0

Co to jest przestrzeń nazw, aby dodać AntiForgery. Próbowałem włączyć system.web.helper, ale nie ma on antyspamu !!!! – sarathkumar

+2

Przestrzeń nazw to System.Web.Helpers w pakiecie Nuget Microsoft.AspNet.WebPages. – Saftpresse99

-4

Można skorzystać z poniższego fragmentu kodu, który sprawdzi wniosek których pochodzi

if ((context.Request.UrlReferrer == null || context.Request.Url.Host != context.Request.UrlReferrer.Host)) 
    { 
     context.Response.Redirect("~/error.aspx", false); 
    } 

Działa świetnie dla mnie !!!

+1

To jest złe i niebezpieczne. Ogranicza tylko CSRF do tego samego hosta i może potencjalnie rozerwać prawdziwe żądania, jeśli nagłówek referer zostanie usunięty, co jest stosunkowo powszechne. – Steve