1

I'm wanting to use webapi 2 inside an MVC5 project (AngularJS, not that this should make any difference) to create the following types of routes

        GET api/animals/cats => return cats
        GET api/animals/dogs => return dogs            
        GET api/animals/* => return all animals (e.g. cats+dogs)

Background: What I did to get started was the following;

  1. from visual studio 2013, new empty MVC application
  2. in controller folder, right click add new controller, select WebApi 2 controller

(apologies if this looks like too much information, just here in case different project types result in different illegal character checking. )

I want to be able to have users pass in a '*' character to indicate a wildcard, indicating all animals. To allow this, using webapi, I registered the following test route;

        config.Routes.MapHttpRoute(
            name: RouteNames.Animals,
            routeTemplate: "api/animals/{animal}",
            defaults: new { id = RouteParameter.Optional, controller = "AnimalsApi" }
        );

when I test this, using postman, I receive a 400 bad request response, with the following error message;

A potentially dangerous Request.Path value was detected from the client (*).

I've read a few related blog posts suggesting that this character is evil because of various reasons, some referencing W3.org, however, the rfc1738 spec for (Uniform Resource Locators 'URL') (page3) seems to actually allow the use of '*' unescaped. extract below;

...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL...

Maybe I've misread this? '*' chars appear to have the W3's blessing, but will gleefully crash your nice clean webapi restful(?) webservice.

I really don't like the syntax of having to use queryparams to work around the problem. The following is a quick (and imho, dirty) fix -> GET api/animals/?animal=* this defeats the whole purpose of having a clean route syntax. My question is, why is '' evil? i.e. If I allow it, via requestPathInvalidCharacters in web.config, (only the '' char, none of the other 'known evil' chars, then what would I be risking? ) What pandora's box of hacking woes would I be exposed to?

Update ( after I accepted the correct answer to the question as defined above, prior to this last comment below before I go to bed! Thanks to everyone for the amazingly quick and accurate responses.)

A more interesting discussion might have been had, if I had proposed the following as the example routes; (wink)

api/animals/{type}/{location}/{sex}
...
GET api/animals/*/london/male  => return all male animals in london
GET api/animals/cats/*/female => return all female cats across all locations

thanks all! cheers, A

snowcode
  • 1,033
  • 10
  • 24
  • 2
    Instead of `api/animals/*` your url for "all" should be `api/animals` (without `animal` parameter. Adding `animal = RouteParameter.Optional` to your route should allow you to build correct actions – Claudio Redi Jun 02 '15 at 19:55
  • yup, that's ridiculously easy and simple answer! I'll go with that, but still would like to know why '*' (star) characters are not allowed? – snowcode Jun 02 '15 at 19:58
  • Ah, just realised why I was hoping that asterisk would work; if the only 'optional' parameter is at the end of the querystring then empty equalling all is really easy. I don't believe that strategy works in the following scenario; api/animals/{type}/{location}/{sex} where as far as I can see, without support asterisk, you're left having to use some type of magic string 'all' or similar, which you have to make sure does never exist in your customers types, locations, sexes tables. Furthermore, my stated intent is to have clean restful urls, e.g. api/animals/cats/*/male – snowcode Jun 02 '15 at 21:28
  • ..using asterisks, makes the urls easier to 'scan' and tell from an eyeball that the * means (all) as oposed to matching an exact string called 'all' that may not match any records. – snowcode Jun 02 '15 at 21:29
  • in that case you'll need an special route matching something like `api/animals/all`. – Claudio Redi Jun 02 '15 at 21:31
  • Just realised this question is a semi-duplicate of this question http://stackoverflow.com/questions/4644092/can-an-url-have-an-asterisk – snowcode Jun 02 '15 at 21:36
  • and also semi duplicate of this question, which in my opinion has the best answer as to why asterisks should be percent encoded in all situations except where it has special meaning in the URI scheme. http://stackoverflow.com/questions/25085992/when-should-an-asterisk-be-encoded-in-an-http-url – snowcode Jun 02 '15 at 21:39

1 Answers1

3

My question is, why is '*' evil? i.e. If I allow it, via requestPathInvalidCharacters in web.config

They may have special meaning:

The asterisk ("*", ASCII 2A hex) and exclamation mark ("!" , ASCII 21 hex) are reserved for use as having special signifiance within specific schemes.

I agree with Claudio's comment, that the better option for "anything" is to just omit the term all together.

Community
  • 1
  • 1
vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • I know that's the right thing to do; what about the following route -> /api/staff/*/onpremise ( e.g. /api/staff/{department}/onpremise ) I know we can simply move the param to the end, and absence indicates (wildcard), however that doesnt work if you have more than 1 property? – snowcode Jun 02 '15 at 20:12