6

I'm wondering if my ASP.NET Web API had an XSS vulnerability as my controller didn't have a method to handle the default GET call.

Without the GET method being handled in the code a call to
/api/mycontroller/?<script>alert('hi');</script> would result in:

{"Message":"No HTTP resource was found that matches the request URI
 'http://localhost:8888/api/mycontroller/?'.",
 "MessageDetail":"No action was found on the controller 'MyController' that 
  matches the request."}

Note that the script tags are in the JSON source, they're just not displayed on the page.

Drop the question mark, /api/mycontroller/<script>alert('hi');</script>, and you'll get
"A potentially dangerous Request.Path value was detected from the client (<)." so now an HttpException is protecting the users.

The API's routing is simply the default one:

.Routes.MapHttpRoute(
    "DefaultApi", 
    "api/{controller}/{id}", 
    new { id = RouteParameter.Optional });

and I've now added in a default action method:

[HttpGet]
public HttpResponseMessage Get()
{ 
    // do something. 
}

Putting in this action method, however, could easily be missed when a developer is creating an API, I think.

So I was wondering, is this an exploitable XSS issue?

2
  • Are you saying the XSS attempt is returned in the JSON response? I've actually not tested this with Web API, but normally ASP.NET won't return actual exception messages to remote clients.
    – Steve
    Dec 20, 2013 at 19:37
  • @SteveS Yes, the script tags are in the returned JSON. This is an HttpError rather than an HttpException that Web API is returning.
    – Boggin
    Dec 21, 2013 at 8:41

1 Answer 1

8

This condition was probably not an exploitable XSS vulnerability for most applications. This is more likely a "defense in depth" filter to prevent programmers from unintentionally causing problems.

XSS is solved in an API's by setting the content-type to application/xml or application/json depending on the return data type (and text/plain is also commonly used to prevent XSS). Reflective and Persistent XSS can only be a problem if the page has an HTML content type. DOM based XSS is still a concern for web services. The Content-Security Policy can be used to further restrict the ability to execute JavaScript using HTML injection, and is useful in preventing DOM-based XSS.

When using a modern browser, an XSS payload shouldn't execute on a non-executablite content type. Never the less, it is a good idea to explicitly disable content sniffing for legacy or non-standard browsers:

X-Content-Type-Options: nosniff
18
  • Json can still contain harmful characters, so this isn't really the answer. {'bad':'<script>doBad()</script>'}
    – drogon
    Nov 25, 2014 at 18:54
  • 1
    @drogon I don't see how the OP's example ie exploitable. Perhaps you should write a Proof-of-Concept exploit to prove me wrong.
    – rook
    Nov 25, 2014 at 19:07
  • XSS is not always solved by the content type (read up on "content sniffing" if you want to know why not), but the question said the response was JSON, it did not say what the content type was set to. Nov 16, 2018 at 4:02
  • @Alex Lauerman I know content sniffing quite well, modern browsers will not override valid content-type (if it is missing or unreadable due to a typo, then that is a different story). Overriding the specified content-type with content-sniffing abuses was a reliable exploit against IE not too long ago, but these days browser vendors have gotten a lot smarter about these types of attacks. No browser will execute a JS payload in a application/json, try it, and if you have a valid PoC then i'll change my post.
    – rook
    Nov 18, 2018 at 1:19
  • application/xml with an .html extension or no extension is more commonly sniffed (at least by all browsers as of 2015: pwndizzle.blogspot.com/2015/07/…) I know the original question didn't have an extension, but just mentioning some caveats in case it's helpful for devs reading this. The bigger point is that this question doesn't say what the content type is set to. I am looking at this same error page now. The content type is text/html, even though the body is json (I have zero idea why -- bug?). PoC: example.com/a?b=<script>alert(1)</script> Nov 25, 2018 at 19:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .