Is there any built-in support for validating malicious input within the Web API, similar to forms with MVC?
If not, could anyone suggest a "global" filter/message inpector/whatever to validate against malicious input? I'm trying to avoid validating all of my models/parameters individually...
No, I don't believe there is such support. Here's why. The input validation support with Web Forms/MVC was a stopgap measure. But encoding output is the better XSS fix; validating input doesn't work perfectly, as what input is "bad" depends on how you'll be outputting it (as part of HTML element source, as part of JS source, in an HTML attribute value, as part of a SQL query, etc.).
So I'd recommend against generic, global input validation as the solution to XSS concerns. Instead, make sure you're always encoding input correctly before outputting it (or passing it on to another layer, such as a SQL DB). For output, if you're using the normal Web API mechanisms for returning data (model classes with content negotiation/formatters), the formatters should handle the content type-specific encoding for you.
I believe XSS is not relevant to ASP.NET Web API. Here is why I think so. Suppose, in the request body, say I get a JSON like this "input": "<script>alert('hello');</script>" and the web API stores the "input" which is bound to some property as-is into a database and retrieve it as-is in a subsequent GET request and sends that off to a client, it is still okay. It is the responsibility of the client to ensure this data is escaped correctly. So, when this input property is serialized to say a web application, before it writes to the browser, the client web app must HTML encode. Web API doing this generally does not make sense because a web API can be consumed by other clients say a WPF application where XSS may not be applicable. Or am I missing any specific case you have in mind?
Why dont you use HttpUtility.HtmlEncode?
Input should always be validated. It doesn't matter where it is going. A name field should return a name string, not a jpeg file or for example depending on your environment a SQL attack.
Related
I have an Azure Mobile service with a .Net back end.
In the backend the data object use proper case. for example, MemberNumber.
In the azure client the view models use pascal case memberNumber.
I am using a library that creates an ODATA request and I get:
The query specified in the URI is not valid. Could not find a property named 'memberNumber' on type 'arenaapi.DataObjects.Members'.
That happens with this get:
/tables/members?%24inlinecount=allpages&%24orderby=memberNumber
If I change that the MemberNumber it works.
However, also, if I change the request to:
/tables/members?%24inlinecount=allpages&$orderby=memberNumber
It also works. It seems that the model binding parser is working differently if the $ is encoded or not.
Is there any way I can fix this server side so the encoded request won't return a 400 without changing the memberNumber to MemberNumber?
All the other stuff, posting, patching, etc is properly binding the pascal cased JSON post to proper cased c# data objects.
I am trying to work out a way to provide a CSV download through a Spring 3 Portlet. I have a method that uses the #ResourceMapping annotation to define a handler that takes some report params in the form of a #ModelAttribute, builds the report, and returns it. The catch-22 I am running into is validating the parameters being send in from the client form.
If I make the handler a #ResourceMapping, I can set the headers and write out the report as using the ResourceResponse, but I can't seem to figure out how to redirect the user back to the Portlet view with errors when their input fails validation. However, if I make it an #ActionMapping, I can then check the BindingResults and forward them back to the form as needed, but the ActionResponse doesn't allow me to set the Content-Disposition header nor write out the CSV bytes, which is sort of critical for sending the report back.
I am at a total loss here, as I don't even know what my options are. Is it even possible to do what I am trying to do with a Portlet? Are there other examples I could look at for a possible work-around?
I suggest you to use both #ActionMapping and #ResourceMapping to fulfill your requirement.
As you said you were able to handle the validation errors using the #ActionResponse, I'll tell you how to handle the Resource Streaming.
As you know every #ActionResponse is followed by a #RenderResponse, just return the same view but, with a hidden iframe this time whose src points to the ResourceURL.
Now the Request you receive in #ResourceMapping is something which is already Validated. So, you can now serve your CSV.
I dont know how complex is your UI and if you are using jsp as views in your application. If nicely managed, Validation can be handled by #ResourceMapping.
Thank you
I created an ASP.NET MVC4 Web API service (REST) with a single GET action. The action currently needs 11 input values, so rather than passing all of those values in the URL, I opted to encapsulate those values into a single class type and have it passed as Content-Body. When I test in Fiddler, I specify the verb as GET, and enter the JSON text in the "Request Body" input box. This works great!
The problem is when I attempt to perform Load Testing in Visual Studio 2010 Ultimate. I am able to specify the GET action and the JSON Content-Body just fine. But when I run the Load test, VS reports exceptions of type ProtocolViolationException (Cannot send a content-body with this verb-type) in the test results. The test executes in 1ms so I suspect the exceptions are causing the test to immediately abort. What can I do to avoid those exceptions? I'd prefer to not change my API to use URL arguments just to work-around the test tooling. If I should change the API for other reasons, let me know. Thanks!
I found it easier to put this answer rather than carry on the discussions.
Sending content with GET is not defined in RFC 2616 yet it has not been prohibited. So as far as the spec is concerned we are in a territory that we have to make our judgement.
GET is canonically used to get a resource. So you are retrieving this resource using this verb with the parameters you are sending. Since GET is both safe and idempotent, it is ideal for caching. Caching usually takes place based on the resource URI - and sometimes based on various headers. The point is cache implementations - AFAIK - would not use the GET content (and to be honest I have not seen any GET with content in real world). And it would not make sense to include the content in the key generation since it reduces the scalability of the caches.
If you have parameters to send, they must be in the URI since this is part of what defines that URI. As such, I strongly believe sending content with GET is wrong.
Even when you look at implementations such as OData, they put the criteria in the URI. I cannot imagine your (or any) applications requirements is beyond OData query requirements.
Do I even need this rule anymore?
I don't see any requests incoming for resource.axd files (as opposed to when I ran webform applications)
WebResource.axd is an HTTP Handler that is part of the .NET Framework
that does one thing and one thing only – it is tasked with getting an
embedded resource out of a DLL and returning its content. What DLL to
go to and what embedded resource to take are specified through the
querystring. For instance, a request to
www.yoursite.com/WebResource.axd?d=EqSMS…&t=63421… might return a
particular snippet of JavaScript embedded in a particular assembly.
Its still part of the framework and you can still retrieve embedded resources using the above handler. You dont want your route handler to handle such requests and that is why it is ignored. My guess is that you can get rid of it if you are completely sure that your app/libraries that you use dont use it.
I'm looking for a way to automatically have my RESTful controller, which returns a String, output a pdf file to the calling browser, when the URI has a .pdf at the end:
http://localhost:9090/services-rs/notices/58357.pdf
Without the .pdf at the end, it currently merely returns the String, i.e. plain text, in the browser.
I tried adding:
<entry key="pdf" value="application/pdf"/>
to my mediatypes list in my ContentNegotiatingViewResolver, but evidently that didn't do the trick.
How do I go about this? Is there a 3rd party library I need to use, or does Spring MVC have this ability built-in?
The ContentNegotiatingViewResolver does not use the extension at the end of your URI. It uses the Accept header in the request. If you would like to use the ContentNegotiatingViewResolver, ensure that your Accept header on the client side is using application/pdf.
If this is not possible for you, you will need to have a different controller.