How to restrict API Resources by their full path and verb

5 7 1,825

This article will give you an example on how you manage / restrict access to your API resources by verb and or the full basepath of the API.

Background:

To start this article off I would like to explain some of the common reasons for using this approach.

Common reasons to restrict by verb or base-path:

  • Mixed Protocol Restrictions: I have a resource that i only want to give read-only access to, but have resources that still have write access in the product.
  • Duplicate Path Suffix: I have two api resources that have the same path suffix but are in different proxies and i want to have different rules for access for each resource. e.g.
    • /basepath1/v1/items
    • /basepath2/v1/items

How It Works OOTB:

API Products currently look at a couple of things to validate if the request has access to a particular resource. Products then looks at the API Proxies that are associated and the API resource paths, these paths only compare the path suffix of the URI (everything after the base-path).

How to Extend OOTB Functionality:

There is a variable that if it exists it will be used instead of the proxy.pathsuffix to do the comparisons, that variable is flow.resource.name. So to extend the functionality we have to change the value of this variable before we validate our key or token.

Here is an example of some javascript to add both basepath and pathsuffix into the flow.resource.name variable

try{
  context.setVariable('flow.resource.name','/'+
    context.getVariable('request.verb')+
    context.getVariable('proxy.basepath')+
    context.getVariable('proxy.pathsuffix')
);
}catch(e){
    throw 'Error in Javascript';
}

And in our product we then can add Resources that look like this:

280-resources.jpg

Or if you want to use wildcards you can do something that looks like this

281-resources2.jpg

Note: That you have to use a URL like format to make this work seamlessly

Extra Note: You can use multiple * wildcards but you can't mix * and ** wildcards

Comments
Not applicable

This is not a very RESTful design since you are including the Verb in the resource URL.

There ought to be a way to restrict/allow the Verb in the Product by resource URL.

Not applicable

The external path is still restful the /Verb is only adding to a variable which you are checking during the key or token validation

mdunker
Staff

@Kurt Kanaskie Just to add to Steve's response:

GET /v1/restricted/basepath/resource2

would still be the request, we are just hacking the variable used to check to:

/GET/v1/restricted/basepath/resource2

No verb in the URL.

Not applicable

One thing to note is - this javascript (policy) should be attached in your bundle before your API Key Validation or Access Token Validation policy, for this to take effect.

DChiesa
Staff

Very interesting! @Carlos Eberhardt, I know you'll be interested to see this!

Not applicable

This seems to introduce an unintended vulnerability. It causes Verify-Api-Key policies to validate strictly against the product's resource path (ignoring the product's API proxies). This means I can have a developer app for an unrelated product (in the same org and environment) and as long as the unrelated product has a valid resource path (eg. /**), it will succeed the original Verify-Api-Key policy.

akoo
New Member

@Edward Yes, I am observing the same behavior. While this is a bug, as long as your resource paths are restrictive enough, then the API proxies of the Product become less important. The workaround would be to list every API proxy basepath as a resource path.

As a side note, there is also a missing check for the environment name. While there's a workaround for access tokens (i.e., check for the environment the access token was minted in against the environment for the resource call), there is no apparent solution for API key validation since there is only 1 call.

Version history
Last update:
‎04-06-2015 12:23 PM
Updated by: