How to apply Regular expression Protection policy to all query params at one go

We have to manually apply regex pattern to each of the query params (have around 20 of them) as shown below. Is there a way to apply a common regex pattern to every query param (without defining each of the query param explicitly in the xml)?

 <QueryParam name="firstName">
        <Pattern>[^\w@\n,.*:\- ]+</Pattern>
    </QueryParam>
    <QueryParam name="lastName">
        <Pattern>[^\w@\n,.*:\- ]+</Pattern>
    </QueryParam>
    <QueryParam name="preferredName">
        <Pattern>[^\w@\n,.*:\- ]+</Pattern>
    </QueryParam>
    <QueryParam name="Status">
        <Pattern>[^\w@\n,.*:\- ]+</Pattern>
    </QueryParam>
Solved Solved
1 11 1,817
1 ACCEPTED SOLUTION

No, not with the policy.

You could enumerate the parameters in a JavaScript policy and check the regex against them that way.

If you need help with that, let me know.

View solution in original post

11 REPLIES 11

No, not with the policy.

You could enumerate the parameters in a JavaScript policy and check the regex against them that way.

If you need help with that, let me know.

I see. Can you please show how it can be done via JS policy. Thanks

The code looks basically like this:

var re1 = new RegExp(properties.regex);
var qpnamesString = context.getVariable('message.queryparams.names') + '';
var qpnames = qpnamesString.substr(1, qpnamesString.length - 2).split(', ');
var firstError = false;
qpnames.forEach(function(name){
  if ( ! firstError) {
    var v1 = context.getVariable('message.queryparam.' + name);
    var m1 = v1.match(re1);
    if (m1) {
      firstError = name;
    }
  }
});


if (firstError) {
  context.setVariable('queryparam_error', firstError);
}

You can see it retrieves all query param names, then iterates over each one, testing a regexp against the value. If there is a match, it sets a context variable.

You will need to test the context variable for non-null, to see if the JS found a match. If that's true, you probably want to use a RaiseFault policy to reject the inbound request.

Try the attached as a working example.

apiproxy-js-qparam-check.zip

Why not use the request.uri variable instead? That would validate the entire URL right?

<Variable name="request.uri">
	<Pattern ignoreCase="true">...</Pattern>
</Variable>

Hi Dino, I downloaded the zip, added the proxy bundle and trying to test. Could you please tell me What is a valid request to test the code?

Valid proxy requests would be,

https://org-env.apigee.net/js-qparam-check/t1?q1=@invlid&q2=valid
https://org-env.apigee.net/js-qparam-check/t1?q1=valid1&q2=valid2

@Dino-at-Google, in the unknownRequest Raise Fault you have used, "code" : 404.01 in the Set Payload.

Is there any specific reason to use 404.01? or is it a typo?

Not a Typo. Just a flourish. The http status code is 404 and is returned in the normal way. That 404.01 is part of the payload.

Hi Siddharth, I got it right now. Thank you.

One more question., with the below RouteRule setting in the proxy, the assign message doesn't work.,

<RouteRulename="default"><TargetEndpoint>default</TargetEndpoint></RouteRule>

The JS policy is evaluated, but from there it hits directly the target server and returns the response from there.

When I changed the RouteRule to <RouteRule name="NoRouteRule"/> the evaluation works fine, as the request is not forwarded to a target.

In the attached proxy if you use,

<RouteRulename="default"><TargetEndpoint>default</TargetEndpoint></RouteRule>

an error will occur while saving because there is no TargetEndpoint,

Bundle is invalid. Errors:[Entity : Proxy, Target Not Found: default;].

Yes, that's right.

So, I suppose we need to use conditional targets.

I have a proxy, which has a TargetEndpoint. So if the js evaluation results in error, I have to set RouteRule to default and print the AssignMessage value. If there is no error, then I have to route it to the TargetEndpoint. Any idea how to adapt this to existing code?

I think there is no need to use Route Rules for your requirement.

We can just use a Raise Fault policy with a Condition to stop flow execution.

If there is no error the call would hit the TargetEndpoint.

PFA Proxy for reference. Before hitting Target I am removing URI & Queryparams, you can modify this to match your requirement.

If you have any other questions, please create/open a new question.

7283-apiproxy-js-qparam-check-rev2-2018-09-12.zip