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>&lt;\s*script\b[^&gt;]*&gt;[^&lt;]+&lt;\s*/\s*script\s*&gt;</Pattern>
    </URIPath>
    <QueryParam name="query">
        <Pattern>&lt;\s*script\b[^&gt;]*&gt;[^&lt;]+&lt;\s*/\s*script\s*&gt;</Pattern>
    </QueryParam>
    <Variable name="request.uri">
        <Pattern>&lt;\s*script\b[^&gt;]*&gt;[^&lt;]+&lt;\s*/\s*script\s*&gt;</Pattern>
    </Variable>
</RegularExpressionProtection>

I'm simulating an injection:
https://host/path/path?page<script>alert(1)</script>&/

The request is accepted normally... (200 ok)

 

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

<Pattern>&lt;[\s]*(?i)[a-zA-Z\s]+\b[^&gt;]*&gt;[^&lt;]+&lt;[\s]*/\s*[a-zA-Z\s]+[\s]*&gt;</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?

 

 

Solved Solved
0 1 2,333
1 ACCEPTED SOLUTION

The RegularExpressionProtection policy checks URIPath, QueryParams and other variables. 

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

  • The URIPath is... the path.  Since your <script> 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 <script> 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>&lt;\s*script\b[^&gt;]*&gt;[^&lt;]+&lt;\s*/\s*script\s*&gt;</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"
        }
    }
}

 

 

View solution in original post

1 REPLY 1

The RegularExpressionProtection policy checks URIPath, QueryParams and other variables. 

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

  • The URIPath is... the path.  Since your <script> 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 <script> 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>&lt;\s*script\b[^&gt;]*&gt;[^&lt;]+&lt;\s*/\s*script\s*&gt;</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"
        }
    }
}