How to prevent 'script injection' in URL correctly?

I’m using “RegularExpressionProtection” policy to prevent Script and SQL Injection. When implementing SQL protection, I was successful, but Script protection was not.

I’m using the following code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RegularExpressionProtection async="false" continueOnError="false" enabled="true" name="Regex-ScriptInjection">
    <DisplayName>Regex-ScriptInjection</DisplayName>
    <Properties/>
    <Source>request</Source>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
    <URIPath>
        <Pattern><\s*script\b[^>]*>[^<]+<\s*/\s*script\s*></Pattern>
    </URIPath>
    <QueryParam name="query">
        <Pattern><\s*script\b[^>]*>[^<]+<\s*/\s*script\s*></Pattern>
    </QueryParam>
    <Variable name="request.uri">
        <Pattern><\s*script\b[^>]*>[^<]+<\s*/\s*script\s*></Pattern>
    </Variable>
</RegularExpressionProtection>

I’m simulating an injection:
https://host/path/path?page&/

The request is accepted normally… (200 ok)

I also changed the default documentation regex, still to no avail:

<Pattern><[\s]*(?i)[a-zA-Z\s]+\b[^>]*>[^<]+<[\s]*/\s*[a-zA-Z\s]+[\s]*></Pattern>

the regex is correct (validated here: https://regex101.com/). But I’m not able to block the request.

What could I be doing wrong?

The RegularExpressionProtection policy checks URIPath, QueryParams and other variables.

The URIPath and the QueryParam elements in your policy will not scan the text.

  • The URIPath is… the path. Since your tag follows the question mark, it’s not part of the path.
  • The QueryParam element refers to a particular query param, which is named “query”. So that won’t include the tag.

The request.uri variable is what you want to scan, for your particular case. BUT, it’s encoded. So you’d need to decode it before scanning. I did this with a JS policy:

<Javascript name='JS-Decode-URI'>
  <Properties>
    <Property name='output-var'>decoded</Property>
    <Property name='input-var'>request.uri</Property>
  </Properties>
  <Source>
var s = context.getVariable(properties['input-var']);
context.setVariable(properties['output-var'], decodeURIComponent(s));
  </Source>
</Javascript>

And then used this RegularExpressionProtection policy

<RegularExpressionProtection name="REP-3">
  <Source>request</Source>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <Variable name="decoded">
    <Pattern><\s*script\b[^>]*>[^<]+<\s*/\s*script\s*></Pattern>
  </Variable>
</RegularExpressionProtection>

And when I send in this request

curl -i 'https://MYORG-MYENV.apigee.net/regex-protect-uri/t3?page<script>alert(1)</script>&'

I get this fault:

{
    "fault": {
        "faultstring": "Regular Expression Threat Detected in REP-3: regex: <\s*script\b[^>]*>[^<]+<\s*/\s*script\s*> input: /regex-protect-uri/t3?page<script>alert(1)</script>",
        "detail": {
            "errorcode": "steps.regexprotection.ThreatDetected"
        }
    }
}
2 Likes