Skip to content

Commit 6cb0c8c

Browse files
authored
Add smoke test for user defined browser AP policy (#1638)
1 parent 8c6d11c commit 6cb0c8c

File tree

2 files changed

+128
-7
lines changed

2 files changed

+128
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
apiVersion: appprotect.f5.com/v1beta1
2+
kind: APPolicy
3+
metadata:
4+
name: ap-user-def-browser
5+
spec:
6+
policy:
7+
applicationLanguage: utf-8
8+
name: user_defrined_browser
9+
template:
10+
name: POLICY_TEMPLATE_NGINX_BASE
11+
browser-definitions:
12+
- name: CustomBrowser1
13+
matchString: custombrowser1/0.1
14+
- name: CustomBrowser2
15+
matchRegex: custombrowser2/0.1
16+
bot-defense:
17+
mitigations:
18+
classes:
19+
- name: browser
20+
action: block
21+
- name: unknown
22+
action: alarm
23+
browsers:
24+
- name: safari
25+
action: alarm
26+
- name: chrome
27+
action: block
28+
- name: firefox
29+
action: alarm
30+
- name: CustomBrowser1
31+
action: block
32+
- name: CustomBrowser2
33+
action: alarm

tests/suite/test_app_protect.py

+95-7
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ def test_responses_dataguard_alarm(
124124
print("------------- Run test for AP policy: dataguard-alarm --------------")
125125
print(f"Request URL: {backend_setup.req_url} and Host: {backend_setup.ingress_host}")
126126

127-
ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
127+
ensure_response_from_backend(
128+
backend_setup.req_url, backend_setup.ingress_host, check404=True
129+
)
128130

129131
print("----------------------- Send valid request ----------------------")
130132
resp_valid = requests.get(
@@ -156,7 +158,9 @@ def test_responses_file_block(
156158
print("------------- Run test for AP policy: file-block --------------")
157159
print(f"Request URL: {backend_setup.req_url} and Host: {backend_setup.ingress_host}")
158160

159-
ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
161+
ensure_response_from_backend(
162+
backend_setup.req_url, backend_setup.ingress_host, check404=True
163+
)
160164

161165
print("----------------------- Send valid request ----------------------")
162166
resp_valid = requests.get(
@@ -188,7 +192,9 @@ def test_responses_malformed_block(
188192
print("------------- Run test for AP policy: malformed-block --------------")
189193
print(f"Request URL: {backend_setup.req_url} and Host: {backend_setup.ingress_host}")
190194

191-
ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
195+
ensure_response_from_backend(
196+
backend_setup.req_url, backend_setup.ingress_host, check404=True
197+
)
192198

193199
print("----------------------- Send valid request with no body ----------------------")
194200
headers = {"host": backend_setup.ingress_host}
@@ -220,7 +226,12 @@ def test_responses_malformed_block(
220226

221227
@pytest.mark.parametrize("backend_setup", [{"policy": "csrf"}], indirect=True)
222228
def test_responses_csrf(
223-
self, kube_apis, ingress_controller_endpoint, crd_ingress_controller_with_ap, backend_setup, test_namespace
229+
self,
230+
kube_apis,
231+
ingress_controller_endpoint,
232+
crd_ingress_controller_with_ap,
233+
backend_setup,
234+
test_namespace,
224235
):
225236
"""
226237
Test CSRF (Cross Site Request Forgery) AppProtect policy: Block requests with invalid/null/non-https origin-header
@@ -229,13 +240,19 @@ def test_responses_csrf(
229240
print(f"Request URL without CSRF protection: {backend_setup.req_url}")
230241
print(f"Request URL with CSRF protection: {backend_setup.req_url_2}")
231242

232-
ensure_response_from_backend(backend_setup.req_url_2, backend_setup.ingress_host, check404=True)
243+
ensure_response_from_backend(
244+
backend_setup.req_url_2, backend_setup.ingress_host, check404=True
245+
)
233246

234247
print("----------------------- Send request with http origin header ----------------------")
235248

236249
headers = {"host": backend_setup.ingress_host, "Origin": "http://appprotect.example.com"}
237-
resp_valid = requests.post(backend_setup.req_url, headers=headers, verify=False, cookies={"flavor": "darkchoco"})
238-
resp_invalid = requests.post(backend_setup.req_url_2, headers=headers, verify=False, cookies={"flavor": "whitechoco"})
250+
resp_valid = requests.post(
251+
backend_setup.req_url, headers=headers, verify=False, cookies={"flavor": "darkchoco"}
252+
)
253+
resp_invalid = requests.post(
254+
backend_setup.req_url_2, headers=headers, verify=False, cookies={"flavor": "whitechoco"}
255+
)
239256

240257
print(resp_valid.text)
241258
print(resp_invalid.text)
@@ -246,3 +263,74 @@ def test_responses_csrf(
246263
assert invalid_resp_title in resp_invalid.text
247264
assert invalid_resp_body in resp_invalid.text
248265
assert resp_invalid.status_code == 200
266+
267+
@pytest.mark.parametrize("backend_setup", [{"policy": "ap-user-def-browser"}], indirect=True)
268+
def test_responses_user_def_browser(
269+
self,
270+
crd_ingress_controller_with_ap,
271+
backend_setup,
272+
):
273+
"""
274+
Test User defined browser AppProtect policy: Block requests from built-in and user-defined browser based on action in policy.
275+
"""
276+
print("------------- Run test for AP policy: User Defined Browser --------------")
277+
print(f"Request URL: {backend_setup.req_url}")
278+
279+
ensure_response_from_backend(
280+
backend_setup.req_url, backend_setup.ingress_host, check404=True
281+
)
282+
283+
print("----------------------- Send request with User-Agent: browser ----------------------")
284+
285+
headers_firefox = {
286+
"host": backend_setup.ingress_host,
287+
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/59.0",
288+
}
289+
resp_firefox = requests.get(backend_setup.req_url, headers=headers_firefox, verify=False)
290+
headers_chrome = {
291+
"host": backend_setup.ingress_host,
292+
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Chrome/76.0.3809.100",
293+
}
294+
resp_chrome = requests.get(backend_setup.req_url_2, headers=headers_chrome, verify=False)
295+
headers_safari = {
296+
"host": backend_setup.ingress_host,
297+
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Safari/537.36",
298+
}
299+
resp_safari = requests.get(backend_setup.req_url_2, headers=headers_safari, verify=False)
300+
headers_custom1 = {
301+
"host": backend_setup.ingress_host,
302+
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 custombrowser1/0.1",
303+
}
304+
resp_custom1 = requests.get(backend_setup.req_url_2, headers=headers_custom1, verify=False)
305+
headers_custom2 = {
306+
"host": backend_setup.ingress_host,
307+
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 custombrowser2/0.1",
308+
}
309+
resp_custom2 = requests.get(backend_setup.req_url_2, headers=headers_custom2, verify=False)
310+
311+
assert (
312+
200
313+
== resp_firefox.status_code
314+
== resp_chrome.status_code
315+
== resp_safari.status_code
316+
== resp_custom1.status_code
317+
== resp_custom2.status_code
318+
)
319+
assert (
320+
valid_resp_addr in resp_firefox.text
321+
and valid_resp_addr in resp_safari.text
322+
and valid_resp_addr in resp_custom2.text
323+
)
324+
assert (
325+
valid_resp_name in resp_firefox.text
326+
and valid_resp_name in resp_safari.text
327+
and valid_resp_name in resp_custom2.text
328+
)
329+
assert (
330+
invalid_resp_title in resp_chrome.text and
331+
invalid_resp_title in resp_custom1.text
332+
)
333+
assert (
334+
invalid_resp_body in resp_chrome.text and
335+
invalid_resp_body in resp_custom1.text
336+
)

0 commit comments

Comments
 (0)