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?

Boggin
  • 205
  • 1
  • 3
  • 6
  • 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 '13 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 '13 at 08:41

1 Answers1

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
rook
  • 46,916
  • 10
  • 92
  • 181
  • Json can still contain harmful characters, so this isn't really the answer. {'bad':''} – drogon Nov 25 '14 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 '14 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. – Alex Lauerman Nov 16 '18 at 04: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 '18 at 01:19
  • `application/xml` with an .html extension or no extension is more commonly sniffed (at least by all browsers as of 2015: http://pwndizzle.blogspot.com/2015/07/xss-extensions-and-content-types.html) 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= – Alex Lauerman Nov 25 '18 at 19:06
  • @Alex Lauerman 2015 is old - that was even before Edge. Alert box or gtfo. – rook Nov 27 '18 at 01:41
  • @rook I have an alert box working on this page. – Alex Lauerman Nov 28 '18 at 15:02
  • @Alex Lauerman Link? I'm really curious. – rook Nov 29 '18 at 08:43
  • It's not public, unfortunately. I looked on shodan for an example I could provide, and it looks like most correctly set the content type to appliction/json (preventing XSS in this case), so I'm not sure if this was a bug in a certain version or what. DM me on twitter or something if you want to have a more detailed discussion. – Alex Lauerman Nov 30 '18 at 13:30
  • @Alex Lauerman It should be trivial to setup a server to test this, if you don't have a PoC link then I'm not changing my security.se post. If you have a link, then i have some bug bounties to fill out ;) – rook Dec 02 '18 at 01:53
  • @Alex Lauerman no PoC? – rook Dec 07 '18 at 06:37
  • @rook I already provided a PoC URL when you asked. I don't have time to setup a server for you right now, especially since I already know it works. Why don't you set a server up if it's trivial? Why you are being so skeptical? Do you not believe this page could have a non-json content type? Look on shodan. This page has 4-5 different content types. – Alex Lauerman Dec 08 '18 at 13:56
  • @Alex Lauerman I don't see a PoC with an alert box. I can't get it to work on any modern browser. There are plenty of RCEs that work on a 3 year old browser. – rook Dec 11 '18 at 07:40
  • It worked fine on latest Firefox for me. Why would you need a PoC to understand that content-type: text/html would execute JavaScript? Are you 1) not believing me that this can exist, or are you 2) not understanding how this is working? I'm completely baffled why you are being so combative. I can't think of a single instance I've ever seen anyone give a PoC for a live server. – Alex Lauerman Dec 12 '18 at 13:57
  • @Alex Lauerman Oh shit i'm so sorry, yeah text/html will always execute javascript on every browser - i thought you where saying the content-types listed in my post executed javascript! What a mistake, i'm so sorry. Yeah of course HTML executes javascript, i didn't think that was up for debate. – rook Dec 13 '18 at 04:58
  • @Alex Lauerman I re-read my post, and i agree, no changes what so ever need to be made. text/html will always execute javascript - rightfully so. – rook Dec 13 '18 at 05:00
  • @rook no worries. I know you are busy on here. I also agree no changes are needed, but I do think your answer could be interpreted dangerously when application/json is set with an .html extension (which is definitely not the case here). I have not seen an updated list of content sniffing behaviors, so I can't say for sure how this would behave. – Alex Lauerman Dec 17 '18 at 02:12
  • @Alex Lauerman I have tested this case, the `content-type` header is taken as the authoritative. I agree, app development dangerous in the hands of the novice who thinks they have a grasp on this complexity. – rook Dec 17 '18 at 05:04