{
  "encassConfigs": [
    {
      "goid": "a1b2c3d4111142229333444455556666",
      "guid": "a1b2c3d4-1111-4222-9333-444455556666",
      "name": "ThreatProtection-1.0",
      "description": "Layered threat protection for JSON and XML APIs. Applies (in order) a request size limit, SQL injection protection, cross-site scripting protection, generic code-injection protection, and content-type-aware document structure threat protection (JSON for application/*+json content types, XML for application/*+xml content types). Defaults are tuned to be safe for typical request payloads (false positives kept low) but can be tightened by editing the underlying policy fragment. On detection, returns the appropriate HTTP status (413 for size, 400 for content threats) with a JSON error body and sets portal.analytics.response.code so analytics reflect the rejection. Designed to run BEFORE authentication in a Portal Policy Template Category chain.",
      "policyName": "ThreatProtection-1.0",
      "encassArgs": [
        {
          "name": "portal.managed.service.apiId",
          "type": "STRING",
          "ordinal": 1,
          "guiPrompt": false
        },
        {
          "name": "maxRequestSizeBytes",
          "type": "STRING",
          "ordinal": 2,
          "guiPrompt": true,
          "guiLabel": "Max Request Payload Size in Bytes (e.g. 1048576 = 1 MB) *"
        }
      ],
      "encassResults": [
        {
          "name": "errorStatus",
          "type": "STRING"
        },
        {
          "name": "errorReason",
          "type": "STRING"
        },
        {
          "name": "portal.analytics.action",
          "type": "STRING"
        },
        {
          "name": "portal.analytics.api.uuid",
          "type": "STRING"
        },
        {
          "name": "portal.analytics.response.code",
          "type": "STRING"
        }
      ],
      "properties": [
        {
          "name": "allowTracing",
          "value": "false"
        },
        {
          "name": "paletteFolder",
          "value": "customAssertions"
        },
        {
          "name": "passMetricsToParent",
          "value": "false"
        }
      ]
    }
  ],
  "policies": [
    {
      "goid": "b2c3d4e5222243339444555566667777",
      "guid": "b2c3d4e5-2222-4333-9444-555566667777",
      "name": "ThreatProtection-1.0",
      "policyType": "FRAGMENT",
      "enabled": true,
      "folderPath": "/Portal Templates",
      "soap": false,
      "policy": {
        "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wsp:Policy xmlns:L7p=\"http://www.layer7tech.com/ws/policy\" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\">\n    <wsp:All wsp:Usage=\"Required\">\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"ThreatProtection-1.0 - layered threat protection for JSON and XML payloads. Edit limits below as needed for your APIs.\"/>\n        </L7p:CommentAssertion>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 1: initialise analytics + working variables.\"/>\n        </L7p:CommentAssertion>\n        <L7p:SetVariable>\n            <L7p:Base64Expression stringValue=\"JHtyZXF1ZXN0Lmh0dHAudXJpfQ==\"/>\n            <L7p:VariableToSet stringValue=\"portal.analytics.action\"/>\n        </L7p:SetVariable>\n        <L7p:SetVariable>\n            <L7p:Base64Expression stringValue=\"JHtwb3J0YWwubWFuYWdlZC5zZXJ2aWNlLmFwaUlkfQ==\"/>\n            <L7p:VariableToSet stringValue=\"portal.analytics.api.uuid\"/>\n        </L7p:SetVariable>\n        <L7p:SetVariable>\n            <L7p:Base64Expression stringValue=\"\"/>\n            <L7p:VariableToSet stringValue=\"errorStatus\"/>\n        </L7p:SetVariable>\n        <L7p:SetVariable>\n            <L7p:Base64Expression stringValue=\"\"/>\n            <L7p:VariableToSet stringValue=\"errorReason\"/>\n        </L7p:SetVariable>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 2: enforce maximum request payload size (publisher-configured maxRequestSizeBytes).\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <L7p:RequestSizeLimit>\n                <L7p:Limit stringValue=\"${maxRequestSizeBytes}\"/>\n                <L7p:EntireMessage booleanValue=\"true\"/>\n            </L7p:RequestSizeLimit>\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:SetVariable>\n                    <L7p:Base64Expression stringValue=\"NDEz\"/>\n                    <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                </L7p:SetVariable>\n                <L7p:SetVariable>\n                    <L7p:Base64Expression stringValue=\"UmVxdWVzdCBwYXlsb2FkIGV4Y2VlZHMgdGhlIG1heGltdW0gYWxsb3dlZCBzaXplLg==\"/>\n                    <L7p:VariableToSet stringValue=\"errorReason\"/>\n                </L7p:SetVariable>\n            </wsp:All>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 3: SQL injection protection. Targets the URL query string and request body. Conservative protection set: MsSql, OraSql, MetaText. Avoids SqlMeta on its own (high false positive rate against legitimate apostrophes/dashes).\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:ComparisonAssertion>\n                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                    <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                    <L7p:Operator operatorNull=\"null\"/>\n                    <L7p:Predicates predicates=\"included\">\n                        <L7p:item dataType=\"included\">\n                            <L7p:Type variableDataType=\"string\"/>\n                        </L7p:item>\n                        <L7p:item binary=\"included\">\n                            <L7p:Operator operator=\"EMPTY\"/>\n                            <L7p:RightValue stringValue=\"\"/>\n                        </L7p:item>\n                    </L7p:Predicates>\n                </L7p:ComparisonAssertion>\n                <wsp:OneOrMore wsp:Usage=\"Required\">\n                    <L7p:SqlAttackProtectionAssertion>\n                        <L7p:IncludeBody booleanValue=\"true\"/>\n                        <L7p:IncludeUrlPath booleanValue=\"false\"/>\n                        <L7p:IncludeUrlQueryString booleanValue=\"true\"/>\n                        <L7p:Protections sqlProtectionTypeArray=\"included\">\n                            <L7p:item protectionType=\"MsSql\"/>\n                            <L7p:item protectionType=\"OraSql\"/>\n                            <L7p:item protectionType=\"MetaText\"/>\n                        </L7p:Protections>\n                        <L7p:Target target=\"REQUEST\"/>\n                    </L7p:SqlAttackProtectionAssertion>\n                    <wsp:All wsp:Usage=\"Required\">\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"NDAw\"/>\n                            <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                        </L7p:SetVariable>\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"UmVxdWVzdCByZWplY3RlZCBieSBzZWN1cml0eSBwb2xpY3kgKFNRTCBpbmplY3Rpb24gcGF0dGVybiBkZXRlY3RlZCku\"/>\n                            <L7p:VariableToSet stringValue=\"errorReason\"/>\n                        </L7p:SetVariable>\n                    </wsp:All>\n                </wsp:OneOrMore>\n            </wsp:All>\n            <L7p:TrueAssertion/>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 4: cross-site scripting (XSS) protection. Targets URL query string + body.\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:ComparisonAssertion>\n                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                    <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                    <L7p:Operator operatorNull=\"null\"/>\n                    <L7p:Predicates predicates=\"included\">\n                        <L7p:item dataType=\"included\">\n                            <L7p:Type variableDataType=\"string\"/>\n                        </L7p:item>\n                        <L7p:item binary=\"included\">\n                            <L7p:Operator operator=\"EMPTY\"/>\n                            <L7p:RightValue stringValue=\"\"/>\n                        </L7p:item>\n                    </L7p:Predicates>\n                </L7p:ComparisonAssertion>\n                <wsp:OneOrMore wsp:Usage=\"Required\">\n                    <L7p:CrossSiteScriptingProtectionAssertion>\n                        <L7p:IncludeBody booleanValue=\"true\"/>\n                        <L7p:IncludeUrlPath booleanValue=\"false\"/>\n                        <L7p:IncludeUrlQueryString booleanValue=\"true\"/>\n                        <L7p:Target target=\"REQUEST\"/>\n                    </L7p:CrossSiteScriptingProtectionAssertion>\n                    <wsp:All wsp:Usage=\"Required\">\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"NDAw\"/>\n                            <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                        </L7p:SetVariable>\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"UmVxdWVzdCByZWplY3RlZCBieSBzZWN1cml0eSBwb2xpY3kgKGNyb3NzLXNpdGUgc2NyaXB0aW5nIHBhdHRlcm4gZGV0ZWN0ZWQpLg==\"/>\n                            <L7p:VariableToSet stringValue=\"errorReason\"/>\n                        </L7p:SetVariable>\n                    </wsp:All>\n                </wsp:OneOrMore>\n            </wsp:All>\n            <L7p:TrueAssertion/>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 5: generic code-injection protection. Conservative protection set: htmlJavaScriptInjection only. Add phpEvalInjection / shellInjection / ldapDnInjection / ldapSearchInjection in environments where they are warranted (they have higher false-positive rates against natural language).\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:ComparisonAssertion>\n                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                    <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                    <L7p:Operator operatorNull=\"null\"/>\n                    <L7p:Predicates predicates=\"included\">\n                        <L7p:item dataType=\"included\">\n                            <L7p:Type variableDataType=\"string\"/>\n                        </L7p:item>\n                        <L7p:item binary=\"included\">\n                            <L7p:Operator operator=\"EMPTY\"/>\n                            <L7p:RightValue stringValue=\"\"/>\n                        </L7p:item>\n                    </L7p:Predicates>\n                </L7p:ComparisonAssertion>\n                <wsp:OneOrMore wsp:Usage=\"Required\">\n                    <L7p:CodeInjectionProtectionAssertion>\n                        <L7p:IncludeBody booleanValue=\"true\"/>\n                        <L7p:IncludeUrlPath booleanValue=\"false\"/>\n                        <L7p:IncludeUrlQueryString booleanValue=\"true\"/>\n                        <L7p:Protections codeInjectionProtectionTypeArray=\"included\">\n                            <L7p:item protectionType=\"htmlJavaScriptInjection\"/>\n                        </L7p:Protections>\n                        <L7p:Target target=\"REQUEST\"/>\n                    </L7p:CodeInjectionProtectionAssertion>\n                    <wsp:All wsp:Usage=\"Required\">\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"NDAw\"/>\n                            <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                        </L7p:SetVariable>\n                        <L7p:SetVariable>\n                            <L7p:Base64Expression stringValue=\"UmVxdWVzdCByZWplY3RlZCBieSBzZWN1cml0eSBwb2xpY3kgKGNvZGUgaW5qZWN0aW9uIHBhdHRlcm4gZGV0ZWN0ZWQpLg==\"/>\n                            <L7p:VariableToSet stringValue=\"errorReason\"/>\n                        </L7p:SetVariable>\n                    </wsp:All>\n                </wsp:OneOrMore>\n            </wsp:All>\n            <L7p:TrueAssertion/>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 6: document-structure threat protection. Branches on the request Content-Type so JSON-only and XML-only assertions are not run against the wrong payload type. Requests without a JSON or XML content-type (e.g. GET, application/x-www-form-urlencoded) skip this step.\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:ComparisonAssertion>\n                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                    <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                    <L7p:Operator operatorNull=\"null\"/>\n                    <L7p:Predicates predicates=\"included\">\n                        <L7p:item dataType=\"included\">\n                            <L7p:Type variableDataType=\"string\"/>\n                        </L7p:item>\n                        <L7p:item binary=\"included\">\n                            <L7p:Operator operator=\"EMPTY\"/>\n                            <L7p:RightValue stringValue=\"\"/>\n                        </L7p:item>\n                    </L7p:Predicates>\n                </L7p:ComparisonAssertion>\n                <L7p:SetVariable>\n                    <L7p:Base64Expression stringValue=\"JHtyZXF1ZXN0Lmh0dHAuaGVhZGVyLmNvbnRlbnQtdHlwZX0=\"/>\n                    <L7p:VariableToSet stringValue=\"contentType\"/>\n                </L7p:SetVariable>\n                <wsp:OneOrMore wsp:Usage=\"Required\">\n                    <wsp:All wsp:Usage=\"Required\">\n                        <L7p:ComparisonAssertion>\n                            <L7p:CaseSensitive booleanValue=\"false\"/>\n                            <L7p:Expression1 stringValue=\"${contentType}\"/>\n                            <L7p:Operator operatorNull=\"null\"/>\n                            <L7p:Predicates predicates=\"included\">\n                                <L7p:item dataType=\"included\">\n                                    <L7p:Type variableDataType=\"string\"/>\n                                </L7p:item>\n                                <L7p:item binary=\"included\">\n                                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                                    <L7p:Operator operator=\"CONTAINS\"/>\n                                    <L7p:RightValue stringValue=\"json\"/>\n                                </L7p:item>\n                            </L7p:Predicates>\n                        </L7p:ComparisonAssertion>\n                        <wsp:OneOrMore wsp:Usage=\"Required\">\n                            <L7p:JsonDocumentStructureAssertion>\n                                <L7p:CheckContainerDepth booleanValue=\"true\"/>\n                                <L7p:MaxContainerDepth intValue=\"20\"/>\n                                <L7p:CheckObjectEntryCount booleanValue=\"true\"/>\n                                <L7p:MaxObjectEntryCount intValue=\"500\"/>\n                                <L7p:CheckArrayEntryCount booleanValue=\"true\"/>\n                                <L7p:MaxArrayEntryCount intValue=\"1000\"/>\n                                <L7p:CheckEntryNameLength booleanValue=\"true\"/>\n                                <L7p:MaxEntryNameLength intValue=\"256\"/>\n                                <L7p:CheckStringValueLength booleanValue=\"true\"/>\n                                <L7p:MaxStringValueLength intValue=\"65536\"/>\n                                <L7p:Target target=\"REQUEST\"/>\n                            </L7p:JsonDocumentStructureAssertion>\n                            <wsp:All wsp:Usage=\"Required\">\n                                <L7p:SetVariable>\n                                    <L7p:Base64Expression stringValue=\"NDAw\"/>\n                                    <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                                </L7p:SetVariable>\n                                <L7p:SetVariable>\n                                    <L7p:Base64Expression stringValue=\"UmVxdWVzdCByZWplY3RlZCBieSBzZWN1cml0eSBwb2xpY3kgKEpTT04gZG9jdW1lbnQgc3RydWN0dXJlIHRocmVhdCBkZXRlY3RlZCku\"/>\n                                    <L7p:VariableToSet stringValue=\"errorReason\"/>\n                                </L7p:SetVariable>\n                            </wsp:All>\n                        </wsp:OneOrMore>\n                    </wsp:All>\n                    <wsp:All wsp:Usage=\"Required\">\n                        <L7p:ComparisonAssertion>\n                            <L7p:CaseSensitive booleanValue=\"false\"/>\n                            <L7p:Expression1 stringValue=\"${contentType}\"/>\n                            <L7p:Operator operatorNull=\"null\"/>\n                            <L7p:Predicates predicates=\"included\">\n                                <L7p:item dataType=\"included\">\n                                    <L7p:Type variableDataType=\"string\"/>\n                                </L7p:item>\n                                <L7p:item binary=\"included\">\n                                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                                    <L7p:Operator operator=\"CONTAINS\"/>\n                                    <L7p:RightValue stringValue=\"xml\"/>\n                                </L7p:item>\n                            </L7p:Predicates>\n                        </L7p:ComparisonAssertion>\n                        <wsp:OneOrMore wsp:Usage=\"Required\">\n                            <L7p:OversizedTextAssertion>\n                                <L7p:LimitTextChars booleanValue=\"true\"/>\n                                <L7p:MaxTextChars longValue=\"1048576\"/>\n                                <L7p:LimitAttrChars booleanValue=\"true\"/>\n                                <L7p:MaxAttrChars longValue=\"2048\"/>\n                                <L7p:LimitNestingDepth booleanValue=\"true\"/>\n                                <L7p:MaxNestingDepth intValue=\"32\"/>\n                                <L7p:Target target=\"REQUEST\"/>\n                            </L7p:OversizedTextAssertion>\n                            <wsp:All wsp:Usage=\"Required\">\n                                <L7p:SetVariable>\n                                    <L7p:Base64Expression stringValue=\"NDAw\"/>\n                                    <L7p:VariableToSet stringValue=\"errorStatus\"/>\n                                </L7p:SetVariable>\n                                <L7p:SetVariable>\n                                    <L7p:Base64Expression stringValue=\"UmVxdWVzdCByZWplY3RlZCBieSBzZWN1cml0eSBwb2xpY3kgKFhNTCBkb2N1bWVudCBzdHJ1Y3R1cmUgdGhyZWF0IGRldGVjdGVkKS4=\"/>\n                                    <L7p:VariableToSet stringValue=\"errorReason\"/>\n                                </L7p:SetVariable>\n                            </wsp:All>\n                        </wsp:OneOrMore>\n                    </wsp:All>\n                    <L7p:TrueAssertion/>\n                </wsp:OneOrMore>\n            </wsp:All>\n            <L7p:TrueAssertion/>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 7: if a threat was detected, mirror the chosen status code into portal.analytics.response.code so the global Portal analytics policy records the rejection.\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:ComparisonAssertion>\n                    <L7p:CaseSensitive booleanValue=\"false\"/>\n                    <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                    <L7p:Operator operatorNull=\"null\"/>\n                    <L7p:Predicates predicates=\"included\">\n                        <L7p:item dataType=\"included\">\n                            <L7p:Type variableDataType=\"string\"/>\n                        </L7p:item>\n                        <L7p:item binary=\"included\">\n                            <L7p:CaseSensitive booleanValue=\"false\"/>\n                            <L7p:Negated booleanValue=\"true\"/>\n                            <L7p:Operator operator=\"EMPTY\"/>\n                            <L7p:RightValue stringValue=\"\"/>\n                        </L7p:item>\n                    </L7p:Predicates>\n                </L7p:ComparisonAssertion>\n                <L7p:SetVariable>\n                    <L7p:Base64Expression stringValue=\"JHtlcnJvclN0YXR1c30=\"/>\n                    <L7p:VariableToSet stringValue=\"portal.analytics.response.code\"/>\n                </L7p:SetVariable>\n            </wsp:All>\n            <L7p:TrueAssertion/>\n        </wsp:OneOrMore>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 8: export analytics + working variables so a parent template / global analytics policy can read them.\"/>\n        </L7p:CommentAssertion>\n        <L7p:ExportVariables>\n            <L7p:ExportedVars stringArrayValue=\"included\">\n                <L7p:item stringValue=\"errorStatus\"/>\n                <L7p:item stringValue=\"errorReason\"/>\n                <L7p:item stringValue=\"portal.analytics.action\"/>\n                <L7p:item stringValue=\"portal.analytics.api.uuid\"/>\n                <L7p:item stringValue=\"portal.analytics.response.code\"/>\n            </L7p:ExportedVars>\n        </L7p:ExportVariables>\n        <L7p:CommentAssertion>\n            <L7p:Comment stringValue=\"Step 9: if a threat was detected, return a JSON error response and short-circuit the policy. The body intentionally does NOT echo the offending payload (avoids leaking what triggered the rule to a probing attacker).\"/>\n        </L7p:CommentAssertion>\n        <wsp:OneOrMore wsp:Usage=\"Required\">\n            <L7p:ComparisonAssertion>\n                <L7p:CaseSensitive booleanValue=\"false\"/>\n                <L7p:Expression1 stringValue=\"${errorStatus}\"/>\n                <L7p:Operator operatorNull=\"null\"/>\n                <L7p:Predicates predicates=\"included\">\n                    <L7p:item dataType=\"included\">\n                        <L7p:Type variableDataType=\"string\"/>\n                    </L7p:item>\n                    <L7p:item binary=\"included\">\n                        <L7p:Operator operator=\"EMPTY\"/>\n                        <L7p:RightValue stringValue=\"\"/>\n                    </L7p:item>\n                </L7p:Predicates>\n            </L7p:ComparisonAssertion>\n            <wsp:All wsp:Usage=\"Required\">\n                <L7p:CustomizeErrorResponse>\n                    <L7p:Content stringValue=\"{&quot;error&quot;:{&quot;code&quot;:${errorStatus},&quot;message&quot;:&quot;${errorReason}&quot;}}\"/>\n                    <L7p:ContentType stringValue=\"application/json\"/>\n                    <L7p:ExtraHeaders nameValuePairArray=\"included\"/>\n                    <L7p:HttpStatus stringValue=\"${errorStatus}\"/>\n                </L7p:CustomizeErrorResponse>\n                <L7p:FalseAssertion/>\n            </wsp:All>\n        </wsp:OneOrMore>\n    </wsp:All>\n</wsp:Policy>\n"
      }
    }
  ],
  "properties": {
    "defaultAction": "NEW_OR_UPDATE",
    "meta": {
      "name": "ThreatProtection-1.0 Bundle",
      "schema": "11.2.1"
    },
    "mappings": {}
  }
}