3 Condition Requirement Custom Rule

Answer these questions to help the Community help you with Security questions.

What is the domain name?
I do not wish to disclose

Have you searched for an answer?
Yes

Please share your search results url:

The following are topics from documentation. I cannot make links.
Rule expressions · Cloudflare Ruleset Engine docs

Rule operators and grouping symbols · Cloudflare Ruleset Engine docs

Values · Cloudflare Ruleset Engine docs

When you tested your domain, what were the results?
Results seem to pass at the introduction of 3 conditions.

Describe the issue you are having:
Background: I have multiple APIs open for partners. Currently we control access in Azure WAF based off 3 conditions:

  • API (hostname) Vendor Needs
  • Vendor Source IP
  • URI vendor wishes to access

I am having issues replicating this behavior in Cloudflare with custom WAF rules. I seem to be able to get 2 conditions to work, but when I try to combine into a single expression/rule, the process breaks. For example, the following two independent statements work:

Host is test-api and ip source not in list:

http.host eq test-api.example.comand notip.src in $dep_val_list_01`

Host is test-api and URI is not:

http.host eq `test-api.example.com` and not `http.request.uri eq "/path/to/option1/test1" or http.request.uri eq "/path/to/option1/test2" or http.request.uri eq "/path/to/test3"

Both of the condition above have an action of “Block” associated with them. The intent here is to restrict/allowlist vendors to specific APIs/URIs and block everything else. I have multiple other api’s for various platforms we offer to our vendors. These all need their own specific logics as well (test2-api, test3-api"). These are all accomplished with multiple WAF policies in Azure.

What error message or number are you receiving?
Error that occurs is that when a third condition is added to the statement set, everything seems to be allowed.

What steps have you taken to resolve the issue?

  1. Tried different syntax methods
  2. Opened ticket with support
  3. Reached out to sales team for escalation

Was the site working with SSL prior to adding it to Cloudflare?
n/a

What are the steps to reproduce the error:

Have you tried from another browser and/or incognito mode?

Please attach a screenshot of the error:

Hi there,

If both expressions work individually and the action is set to block on both, to merge them into a single expression, you only need to separate it by OR

1st expression:
(http.host eq "test-api.example.com" and http.request.uri ne "/path/to/option1/test1") or (http.request.uri eq "/path/to/option1/test2") or (http.request.uri eq "/path/to/test3")

2nd expression:
(http.host eq "test-api.example.com" and not ip.src in $dep_val_list_01)

Combined expression:
(http.host eq "test-api.example.com" and http.request.uri ne "/path/to/option1/test1") or (http.request.uri eq "/path/to/option1/test2") or (http.request.uri eq "/path/to/test3") or (http.host eq "test-api.example.com" and not ip.src in $dep_val_list_01)

Take care.

So I tried this and it didn’t work. I ran through a few different iterations of it and in a single line expression, it just doesn’t seem to work at all. So, then I was curious what would happen if I defined it in 2 different rules and applied it like that. Interestingly enough, if I create 2 custom rules. It “appears” to work as intended. So for example:

Custom Rule 1:

(http.host eq "test-api.example.com" and not (http.request.uri eq "/path/to/option/test1" or http.request.uri eq "/path/to/option/test2" or http.request.uri eq "/path/to/option/test3"))

Custom Rule 2:

http.host eq "test-api.example.com" and not ip.src in $dep_val_list_01

I am still going through a bunch of test cases but so far, I’ve tried 3 different tests:

  1. Post request to test-api.example.com/path/to/option/test1 from an IP in $dep_vap_list_01 (success)
  2. Post request to test-api.example.com/path/to/option/test1 from an IP NOT in $dep_vap_list_01 (fail)
  3. Post request to test-api.example.com/path/to/option/test4 from an IP in $dep_vap_list_01 (fail)

So those 3 test examples seem to be working. I need to do some further testing.