Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add smoke test for user defined browser AP policy #1638

Merged
merged 1 commit into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions tests/data/appprotect/ap-user-def-browser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: appprotect.f5.com/v1beta1
kind: APPolicy
metadata:
name: ap-user-def-browser
spec:
policy:
applicationLanguage: utf-8
name: user_defrined_browser
template:
name: POLICY_TEMPLATE_NGINX_BASE
browser-definitions:
- name: CustomBrowser1
matchString: custombrowser1/0.1
- name: CustomBrowser2
matchRegex: custombrowser2/0.1
bot-defense:
mitigations:
classes:
- name: browser
action: block
- name: unknown
action: alarm
browsers:
- name: safari
action: alarm
- name: chrome
action: block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's not your favourite browser 😆

- name: firefox
action: alarm
- name: CustomBrowser1
action: block
- name: CustomBrowser2
action: alarm
102 changes: 95 additions & 7 deletions tests/suite/test_app_protect.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ def test_responses_dataguard_alarm(
print("------------- Run test for AP policy: dataguard-alarm --------------")
print(f"Request URL: {backend_setup.req_url} and Host: {backend_setup.ingress_host}")

ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
ensure_response_from_backend(
backend_setup.req_url, backend_setup.ingress_host, check404=True
)

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

ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
ensure_response_from_backend(
backend_setup.req_url, backend_setup.ingress_host, check404=True
)

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

ensure_response_from_backend(backend_setup.req_url, backend_setup.ingress_host, check404=True)
ensure_response_from_backend(
backend_setup.req_url, backend_setup.ingress_host, check404=True
)

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

@pytest.mark.parametrize("backend_setup", [{"policy": "csrf"}], indirect=True)
def test_responses_csrf(
self, kube_apis, ingress_controller_endpoint, crd_ingress_controller_with_ap, backend_setup, test_namespace
self,
kube_apis,
ingress_controller_endpoint,
crd_ingress_controller_with_ap,
backend_setup,
test_namespace,
):
"""
Test CSRF (Cross Site Request Forgery) AppProtect policy: Block requests with invalid/null/non-https origin-header
Expand All @@ -229,13 +240,19 @@ def test_responses_csrf(
print(f"Request URL without CSRF protection: {backend_setup.req_url}")
print(f"Request URL with CSRF protection: {backend_setup.req_url_2}")

ensure_response_from_backend(backend_setup.req_url_2, backend_setup.ingress_host, check404=True)
ensure_response_from_backend(
backend_setup.req_url_2, backend_setup.ingress_host, check404=True
)

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

headers = {"host": backend_setup.ingress_host, "Origin": "http://appprotect.example.com"}
resp_valid = requests.post(backend_setup.req_url, headers=headers, verify=False, cookies={"flavor": "darkchoco"})
resp_invalid = requests.post(backend_setup.req_url_2, headers=headers, verify=False, cookies={"flavor": "whitechoco"})
resp_valid = requests.post(
backend_setup.req_url, headers=headers, verify=False, cookies={"flavor": "darkchoco"}
)
resp_invalid = requests.post(
backend_setup.req_url_2, headers=headers, verify=False, cookies={"flavor": "whitechoco"}
)

print(resp_valid.text)
print(resp_invalid.text)
Expand All @@ -246,3 +263,74 @@ def test_responses_csrf(
assert invalid_resp_title in resp_invalid.text
assert invalid_resp_body in resp_invalid.text
assert resp_invalid.status_code == 200

@pytest.mark.parametrize("backend_setup", [{"policy": "ap-user-def-browser"}], indirect=True)
def test_responses_user_def_browser(
self,
crd_ingress_controller_with_ap,
backend_setup,
):
"""
Test User defined browser AppProtect policy: Block requests from built-in and user-defined browser based on action in policy.
"""
print("------------- Run test for AP policy: User Defined Browser --------------")
print(f"Request URL: {backend_setup.req_url}")

ensure_response_from_backend(
backend_setup.req_url, backend_setup.ingress_host, check404=True
)

print("----------------------- Send request with User-Agent: browser ----------------------")

headers_firefox = {
"host": backend_setup.ingress_host,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/59.0",
}
resp_firefox = requests.get(backend_setup.req_url, headers=headers_firefox, verify=False)
headers_chrome = {
"host": backend_setup.ingress_host,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Chrome/76.0.3809.100",
}
resp_chrome = requests.get(backend_setup.req_url_2, headers=headers_chrome, verify=False)
headers_safari = {
"host": backend_setup.ingress_host,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Safari/537.36",
}
resp_safari = requests.get(backend_setup.req_url_2, headers=headers_safari, verify=False)
headers_custom1 = {
"host": backend_setup.ingress_host,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 custombrowser1/0.1",
}
resp_custom1 = requests.get(backend_setup.req_url_2, headers=headers_custom1, verify=False)
headers_custom2 = {
"host": backend_setup.ingress_host,
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 custombrowser2/0.1",
}
resp_custom2 = requests.get(backend_setup.req_url_2, headers=headers_custom2, verify=False)

assert (
200
== resp_firefox.status_code
== resp_chrome.status_code
== resp_safari.status_code
== resp_custom1.status_code
== resp_custom2.status_code
)
assert (
valid_resp_addr in resp_firefox.text
and valid_resp_addr in resp_safari.text
and valid_resp_addr in resp_custom2.text
)
assert (
valid_resp_name in resp_firefox.text
and valid_resp_name in resp_safari.text
and valid_resp_name in resp_custom2.text
)
assert (
invalid_resp_title in resp_chrome.text and
invalid_resp_title in resp_custom1.text
)
assert (
invalid_resp_body in resp_chrome.text and
invalid_resp_body in resp_custom1.text
)