2012-03-14 17 views
11

Mam problemy z żądaniami, które zawierają "niebezpieczne znaki" jako część adresu URL interfejsu API sieci Web. Adres URL zawiera kod &, który jest poprawnie zakodowany za pomocą adresu URL, ale nadal powoduje błąd ASP.NET sprawdzania poprawności żądania.Jak przesłonić wartość RequestValidation w ASP.NET WebAPI

W przeciwieństwie do MVC wydaje się, że nie ma atrybutu [ValidateInput (false)], aby wymusić i wyłączyć tę funkcję.

Odpowiedz

8

Okazuje się, że odpowiedź jest to zrobić w pliku web.config przy użyciu:

<system.web> 
    <httpRuntime requestPathInvalidCharacters="" /> 
</system.web> 

Można ustawić to globalnie lub na poziomie sub-katalogów. Możesz użyć elementu <location path="">, aby określić to ustawienie tylko pod określonymi ścieżkami. Na przykład, jeśli trasa Web API, które wpłynęły żył pod spodem api/images można wykonać następujące czynności:

<location path="api/images"> 
    <system.web> 
    <httpRuntime requestPathInvalidCharacters="" /> 
    </system.web> 
</location> 

Więcej informacji: https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx

+0

To jedyne rozwiązanie, które sprawdziło się u mnie. Dodanie 'requestValidationMode = '2.0'' do pliku web.config i wypróbowanie atrybutu" [ValidateInput (false)] "w metodzie akcji NIE działa.Zaczęło działać po dodaniu 'requestPathInvalidCharacters =" "". Myślę, że to dlatego, że błąd tutaj jest częścią sprawdzania poprawności Request.Path, a nie sprawdzania Request.Form. – quakkels

+0

Nie musi być globalna, wystarczy użyć elementu 'location', aby ograniczyć ścieżkę. Jeśli więc twoja trasa Web API jest pod 'api/foo' możesz ograniczyć lokalizację do' path = "api/foo" 'i dodać tam konfigurację' httpRuntime'. Potwierdzone to działa dobrze w IIS. Również MSDN wyraźnie stwierdza, że ​​'' może być "zadeklarowane na poziomie komputera, witryny, aplikacji i podkatalogów". Zaktualizowałem odpowiedź. – kamranicus

1

za @Levi nasz Web Security facet:

Konfiguracja to jedyny sposób, aby to zrobić. Nawet MVC [ValidateInput (false)] nie pomoże w tym konkretnym scenariuszu.

Wyłączenie go w Web.config nie jest konieczny, straszny pomysł. Jeśli stosujesz dobre praktyki bezpieczeństwa, sprawdzając i kodując niezaufane dane, to idealnie nadaje się do zastosowania w całej aplikacji.

+0

'[ValidateInput (false)]' nie działa w moim przypadku. Myślę, że to dlatego, że '[ValidateInput (false)] odnosi się do' Request.Form' zamiast 'Request.Path'. – quakkels

2

Przy ustawieniu RequestValidation na wartość 4,0 w konfiguracji odpowiedź brzmi nie. Można jednak powrócić do wersji 2.0 Request Validation, w której to przypadku atrybut MVC działa tak, jak można się spodziewać: Weryfikuj domyślnie i jawnie wymuszaj w razie potrzeby.

<httpRuntime executionTimeout="300" requestValidationMode="2.0" /> 

Rozmawiałem szczegółowo na ten temat, a niektóre z opcji tutaj: http://www.west-wind.com/weblog/posts/2010/Aug/19/RequestValidation-Changes-in-ASPNET-40

+0

Jest to jedyna opcja, która zadziałała dla mnie. – santos

2

można uzyskać kontrolę nad bardziej precyzyjną nad tym przez ustawienie atrybutu elementu httpRuntimerequestValidationType do rodzaju niestandardowej, która dziedziczy od System.Web.Util.RequestValidator i zastępuje IsValidRequestString.

Niestety, nie jest to część potoku WebAPI, więc nie można bezpośrednio sprawdzić takich rzeczy, jak filtry akcji (tj. Atrybuty w metodach kontrolera). Jeśli jednak szczególnie dotyczy to pól Validation of Form, Validator nie zostanie wywołany, dopóki nie uzyskasz do nich dostępu, co ma miejsce po uruchomieniu Filtru akcji, więc możesz zrezygnować z walidacji za pomocą atrybutu poprzez tworzenie klas jak poniżej ...

public class AllowFormHtmlAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     HttpContext.Current.Items["AllowFormHtml"] = true; 
    } 
} 

public class CustomRequestValidator : RequestValidator 
{ 
    protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) 
    { 
     if (context.Items["AllowFormHtml"] as bool? == true && requestValidationSource == RequestValidationSource.Form) 
     { 
      validationFailureIndex = 0; 
      return true; 
     } 

     return base.IsValidRequestString(
      context, value, requestValidationSource, collectionKey, out validationFailureIndex); 
    } 
} 

... Wtedy właśnie opisywanie metodę kontrolera z [AllowFormHtml]

Jednakże, jeśli masz dostęp pól formularza bezpośrednio z HttpRequest, to prostsze w użyciu HttpRequest.Unvalidated , która pomija sprawdzanie poprawności.

Powiązane problemy