diff --git a/etc/fastly_edge_modules/netacea_integration.json b/etc/fastly_edge_modules/netacea_integration.json index b4d2cc19..3a44475e 100644 --- a/etc/fastly_edge_modules/netacea_integration.json +++ b/etc/fastly_edge_modules/netacea_integration.json @@ -91,12 +91,12 @@ "vcl": [ { "priority": 45, - "template": "set var.fastly_req_do_shield = (req.restarts <= 1);\nset req.http.Fastly-Force-Shield = \"1\";\nif (req.restarts == 0) {\n call cleanup_netacea_variables;\n}\ncall netacea_check_req;\n", + "template": "if (req.restarts == 0) {\n call cleanup_netacea_variables;\n set req.http.x-netacea:do_shield = if(var.fastly_req_do_shield, \"1\", \"0\");\n}\nif (req.restarts > 0 && req.http.x-netacea:restart_triggered == \"1\") {\n if (req.http.x-netacea:do_shield == \"1\") {\n set var.fastly_req_do_shield = true;\n }\n set req.http.Fastly-Force-Shield = \"1\";\n}\ncall netacea_check_req;\n", "type": "recv" }, { "priority": 45, - "template": "if (!is_path_ignored() && !req.is_purge) {\n declare local var.netacea_use_relative_path_captcha_assets STRING;\n declare local var.integration_mode STRING;\n declare local var.mit_svc_latency INTEGER;\n if (req.http.x-netacea:mit_svc_start_time) {\n set var.mit_svc_latency = std.strtol(time.elapsed.msec, 10);\n set var.mit_svc_latency -= std.strtol(req.http.x-netacea:mit_svc_start_time, 10);\n set req.http.x-netacea:mit_svc_latency = var.mit_svc_latency;\n }\n set var.netacea_use_relative_path_captcha_assets = get_netacea_config_use_relative_path_captcha_assets();\n if (var.netacea_use_relative_path_captcha_assets == \"true\") {\n if (std.prefixof(req.url.path, \"/Mitigations/\") && req.method == \"GET\") {\n if (std.suffixof(req.url.path, \".css\") || std.suffixof(req.url.path, \".js\")) {\n return(deliver);\n }\n }\n }\n if (req.http.netacea_captcha_path == \"1\") {\n call netacea_hide_response_headers;\n call set_netacea_captcha_header;\n return(deliver);\n }\n call netacea_calculate_best_mitigation;\n if (req.http.netacea_processed == \"1\") {\n set var.integration_mode = get_netacea_config_integration_mode();\n set req.http.x-netacea:mit_status = resp.status;\n if (resp.status != 200 && req.http.X-Netacea-Compile-JSON != \"done\") {\n set req.http.netacea_best_mitigation = \"\";\n set req.http.netacea_bctype_string = \"\";\n if(req.url == \"/AtaVerifyCaptcha\") {\n unset resp.http.Set-Cookie;\n set req.http.netacea_set_cookies = \"0\";\n }\n }\n if (var.integration_mode == \"MITIGATE\" && req.http.X-Netacea-Compile-JSON != \"done\" && netacea_should_return_json()) { \n if (req.url != \"/AtaVerifyCaptcha\" && resp.http.X-Netacea-Mitigate == \"1\") { \n if (resp.http.X-Netacea-Captcha == \"1\" || resp.http.X-Netacea-Captcha == \"5\") { \n set req.http.X-Netacea-Event-ID = resp.http.X-Netacea-Event-ID;\n set req.http.X-Netacea-Compile-JSON = \"requested\";\n }\n }\n }\n if (var.integration_mode == \"INJECT\" || req.http.X-Netacea-Compile-JSON == \"requested\") {\n set req.http.X-Netacea-Match = \"\" resp.http.X-Netacea-Match;\n set req.http.X-Netacea-Mitigate = \"\" resp.http.X-Netacea-Mitigate;\n set req.http.X-Netacea-Captcha = \"\" resp.http.X-Netacea-Captcha;\n }\n set req.http.netacea_mitata_captcha_cookie_value = resp.http.x-netacea-mitatacaptcha-value;\n set req.http.netacea_mitata_captcha_cookie_expiry = resp.http.x-netacea-mitatacaptcha-expiry;\n call set_netacea_cookies;\n call netacea_hide_response_headers;\n if(req.url == \"/AtaVerifyCaptcha\") {\n return(deliver);\n }\n set req.http.host = req.http.netacea_origin_host;\n set req.url = req.http.netacea_origin_url;\n set req.method = req.http.netacea_origin_method;\n unset req.http.netacea_origin_url;\n unset req.http.netacea_origin_host;\n unset req.http.netacea_origin_method;\n unset req.http.X-Netacea-Api-Key;\n if (\n req.http.netacea_best_mitigation != \"captcha\"\n || var.integration_mode == \"INJECT\"\n || req.http.X-Netacea-Compile-JSON == \"requested\"\n ) {\n unset req.http.x-netacea:netacea_check_req_called;\n restart;\n }\n set resp.status = 403;\n set resp.response = \"Forbidden\";\n unset req.http.X-Netacea-Compile-JSON;\n call set_netacea_captcha_header;\n return(deliver);\n }\n if (fastly.ff.visits_this_service == 0) {\n call set_netacea_cookies;\n }\n}\n", + "template": "if (!is_path_ignored() && !req.is_purge) {\n declare local var.netacea_use_relative_path_captcha_assets STRING;\n declare local var.integration_mode STRING;\n declare local var.mit_svc_latency INTEGER;\n set var.netacea_use_relative_path_captcha_assets = get_netacea_config_use_relative_path_captcha_assets();\n if (var.netacea_use_relative_path_captcha_assets == \"true\") {\n if (std.prefixof(req.url.path, \"/Mitigations/\") && req.method == \"GET\") {\n if (std.suffixof(req.url.path, \".css\") || std.suffixof(req.url.path, \".js\")) {\n return(deliver);\n }\n }\n }\n if (req.http.netacea_captcha_path == \"1\") {\n call netacea_hide_response_headers;\n call set_netacea_captcha_header;\n return(deliver);\n }\n call netacea_calculate_best_mitigation;\n if (req.http.netacea_processed == \"1\") {\n if (req.http.x-netacea:mit_svc_start_time) {\n set var.mit_svc_latency = std.strtol(time.elapsed.msec, 10);\n set var.mit_svc_latency -= std.strtol(req.http.x-netacea:mit_svc_start_time, 10);\n set req.http.x-netacea:mit_svc_latency = var.mit_svc_latency;\n }\n set req.http.x-netacea:mit_status = resp.status;\n if (resp.status != 200 && req.http.X-Netacea-Compile-JSON != \"done\") {\n set req.http.netacea_best_mitigation = \"\";\n set req.http.netacea_bctype_string = \"\";\n if(req.url == \"/AtaVerifyCaptcha\") {\n unset resp.http.Set-Cookie;\n set req.http.netacea_set_cookies = \"0\";\n }\n }\n set var.integration_mode = get_netacea_config_integration_mode();\n if (var.integration_mode == \"MITIGATE\" && req.http.X-Netacea-Compile-JSON != \"done\" && netacea_should_return_json()) { \n if (req.url != \"/AtaVerifyCaptcha\" && resp.http.X-Netacea-Mitigate == \"1\") { \n if (resp.http.X-Netacea-Captcha == \"1\" || resp.http.X-Netacea-Captcha == \"5\") { \n set req.http.X-Netacea-Event-ID = resp.http.X-Netacea-Event-ID;\n set req.http.X-Netacea-Compile-JSON = \"requested\";\n }\n }\n }\n if (var.integration_mode == \"INJECT\" || req.http.X-Netacea-Compile-JSON == \"requested\") {\n set req.http.X-Netacea-Match = \"\" resp.http.X-Netacea-Match;\n set req.http.X-Netacea-Mitigate = \"\" resp.http.X-Netacea-Mitigate;\n set req.http.X-Netacea-Captcha = \"\" resp.http.X-Netacea-Captcha;\n }\n set req.http.netacea_mitata_captcha_cookie_value = resp.http.x-netacea-mitatacaptcha-value;\n set req.http.netacea_mitata_captcha_cookie_expiry = resp.http.x-netacea-mitatacaptcha-expiry;\n call set_netacea_cookies;\n call netacea_hide_response_headers;\n if(req.url == \"/AtaVerifyCaptcha\") {\n return(deliver);\n }\n set req.http.host = req.http.netacea_origin_host;\n set req.url = req.http.netacea_origin_url;\n set req.method = req.http.netacea_origin_method;\n unset req.http.netacea_origin_url;\n unset req.http.netacea_origin_host;\n unset req.http.netacea_origin_method;\n unset req.http.X-Netacea-Api-Key;\n if (\n req.http.netacea_best_mitigation != \"captcha\"\n || var.integration_mode == \"INJECT\"\n || req.http.X-Netacea-Compile-JSON == \"requested\"\n ) {\n unset req.http.x-netacea:netacea_check_req_called;\n set req.http.x-netacea:restart_triggered = \"1\";\n restart;\n }\n set resp.status = 403;\n set resp.response = \"Forbidden\";\n unset req.http.X-Netacea-Compile-JSON;\n call set_netacea_captcha_header;\n return(deliver);\n }\n if (fastly.ff.visits_this_service == 0) {\n call set_netacea_cookies;\n }\n}\n", "type": "deliver" }, { @@ -106,9 +106,9 @@ }, { "priority": 45, - "template": "backend F_MitSvc {\n .between_bytes_timeout = 100ms;\n .connect_timeout = 500ms;\n .dynamic = true;\n .first_byte_timeout = 500ms;\n .host = \"geo-mitigations.netacea.net\";\n .max_connections = 200;\n .port = \"443\";\n .share_key = \"NetaceaGeoMitigations\";\n .host_header = \"geo-mitigations.netacea.net\";\n .always_use_host_header = true;\n .ssl = true;\n .ssl_cert_hostname = \"geo-mitigations.netacea.net\";\n .ssl_check_cert = always;\n .ssl_sni_hostname = \"geo-mitigations.netacea.net\";\n .probe = {\n .dummy = false;\n .initial = 5;\n .request = \"GET /_health HTTP/1.1\" \"Host: geo-mitigations.netacea.net\" \"Connection: close\" \"User-Agent: Varnish/fastly (healthcheck)\";\n .threshold = 1;\n .timeout = 2s;\n .window = 5;\n .expected_response = 200;\n }\n}\nbackend F_CaptchaAssets {\n .between_bytes_timeout = 10s;\n .connect_timeout = 1s;\n .dynamic = true;\n .first_byte_timeout = 15s;\n .host = \"assets.ntcacdn.net\";\n .max_connections = 200;\n .port = \"443\";\n .share_key = \"4nxXnE6VkrJiVuGz4G1VbJ\";\n .host_header = \"assets.ntcacdn.net\";\n .always_use_host_header = true;\n .ssl = true;\n .ssl_cert_hostname = \"assets.ntcacdn.net\";\n .ssl_check_cert = always;\n .ssl_sni_hostname = \"assets.ntcacdn.net\";\n .probe = {\n .dummy = true;\n .initial = 5;\n .request = \"HEAD / HTTP/1.1\" \"Host: assets.ntcacdn.net\" \"Connection: close\";\n .threshold = 1;\n .timeout = 2s;\n .window = 5;\n }\n}\ntable Netacea_Config {\n \"integration_type\": \"fastly/magento\",\n \"integration_version\": \"5.10.1\",\n \"integration_mode\": \"{{netacea_integration_mode}}\",\n \"api_key\": \"{{netacea_api_key}}\",\n \"secret_key\": \"{{netacea_secret}}\",\n \"encryption_key\": \"{{netacea_encryption_key}}\",\n \"cookie_name\": \"{{netacea_cookie_name}}\",\n \"captcha_cookie_name\": \"{{netacea_captcha_cookie_name}}\",\n \"ignore_list\": \"{{netacea_ignore_list}}\",\n \"use_relative_path_captcha_assets\": \"{{netacea_use_relative_path_captcha_assets}}\",\n \"real_ip_header_name\": \"{{netacea_real_ip_header_name}}\",\n \"captcha_path\": \"{{netacea_captcha_path}}\",\n \"captcha_header\": \"{{netacea_captcha_header}}\",\n \"enable_captcha_content_negotiation\": \"{{netacea_enable_ccn}}\"\n}\nsub get_netacea_config_integration_type STRING {\n return table.lookup(Netacea_Config, \"integration_type\", \"\");\n}\nsub get_netacea_config_integration_version STRING {\n return table.lookup(Netacea_Config, \"integration_version\", \"\");\n}\nsub get_netacea_config_api_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"api_key\");\n }\n return table.lookup(Netacea_Config, \"api_key\", \"\");\n}\nsub get_netacea_config_secret_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"secret_key\");\n }\n return table.lookup(Netacea_Config, \"secret_key\", \"\");\n}\nsub get_netacea_config_encryption_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"encryption_key\");\n }\n return table.lookup(Netacea_Config, \"encryption_key\", \"\");\n}\nsub get_netacea_config_integration_mode STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"integration_mode\");\n }\n return table.lookup(Netacea_Config, \"integration_mode\", \"\");\n}\nsub get_netacea_config_ignore_list STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"ignore_list\");\n }\n return table.lookup(Netacea_Config, \"ignore_list\", \"\");\n}\nsub get_netacea_config_cookie_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"cookie_name\");\n }\n return table.lookup(Netacea_Config, \"cookie_name\", \"\");\n}\nsub get_netacea_config_captcha_cookie_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_cookie_name\");\n }\n return table.lookup(Netacea_Config, \"captcha_cookie_name\", \"\");\n}\nsub get_netacea_config_use_relative_path_captcha_assets STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"use_relative_path_captcha_assets\");\n }\n return table.lookup(Netacea_Config, \"use_relative_path_captcha_assets\", \"\");\n}\nsub get_netacea_config_real_ip_header_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"real_ip_header_name\");\n }\n return table.lookup(Netacea_Config, \"real_ip_header_name\", \"\");\n}\nsub get_netacea_config_captcha_path STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_path\");\n }\n return table.lookup(Netacea_Config, \"captcha_path\", \"\");\n}\nsub get_netacea_config_captcha_header STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_header\");\n }\n return table.lookup(Netacea_Config, \"captcha_header\", \"\");\n}\nsub get_netacea_config_enable_captcha_content_negotiation STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"enable_captcha_content_negotiation\");\n }\n return table.lookup(Netacea_Config, \"enable_captcha_content_negotiation\", \"\");\n}\nsub get_sanitised_netacea_config_cookie_name STRING {\n declare local var.name STRING;\n set var.name = get_netacea_config_cookie_name();\n if (var.name ~ \"^\\s*(.*?)\\s*$\") {\n if (re.group.1 != \"\") {\n return re.group.1;\n }\n }\n return \"_mitata\";\n}\nsub get_sanitised_netacea_config_captcha_cookie_name STRING {\n declare local var.name STRING;\n set var.name = get_netacea_config_captcha_cookie_name();\n if (var.name ~ \"^\\s*(.*?)\\s*$\") {\n if (re.group.1 != \"\") {\n return re.group.1;\n }\n }\n return \"_mitatacaptcha\";\n}\ntable Netacea_Match_Dict {\n \"0\": \"\",\n \"1\": \"ua\",\n \"2\": \"ip\",\n \"3\": \"visitor\",\n \"4\": \"datacenter\",\n \"5\": \"customer_session\",\n \"6\": \"organisation\",\n \"7\": \"asn\",\n \"8\": \"country\",\n \"9\": \"combination\"\n}\ntable Netacea_Mitigate_Dict {\n \"0\": \"\",\n \"1\": \"blocked\",\n \"2\": \"allow\",\n \"3\": \"hardblocked\"\n}\ntable Netacea_Best_Mitigations_Dict {\n \"0\": \"\",\n \"1\": \"block\",\n \"2\": \"allow\",\n \"3\": \"block\"\n}\ntable Netacea_Best_Mitigations_Captcha_Dict {\n \"1\": \"captcha\",\n \"2\": \"\",\n \"3\": \"captcha\",\n \"4\": \"\",\n \"5\": \"captcha\"\n}\ntable Netacea_Captcha_Dict {\n \"0\": \"\",\n \"1\": \"captcha_serve\",\n \"2\": \"captcha_pass\",\n \"3\": \"captcha_fail\",\n \"4\": \"captcha_cookiepass\",\n \"5\": \"captcha_cookiefail\",\n}\nsub get_netacea_captcha_path STRING {\n declare local var.path STRING;\n set var.path = get_netacea_config_captcha_path();\n set var.path = regsub(var.path, \"^\\s*/*\", \"/\");\n set var.path = regsub(var.path, \"\\s*$\", \"\");\n return urldecode(var.path);\n}\nsub get_sanitised_netacea_config_captcha_header STRING {\n declare local var.value STRING;\n set var.value = get_netacea_config_captcha_header();\n set var.value = urldecode(regsuball(var.value, \"&#x(.{2});\", \"%25\\1\"));\n set var.value = std.replaceall(var.value, \""\", \"%22\");\n set var.value = std.replaceall(var.value, \"<\", \"<\");\n set var.value = std.replaceall(var.value, \">\", \">\");\n set var.value = std.replaceall(var.value, \"&\", \"&\");\n return var.value;\n}\nsub get_netacea_captcha_header_name STRING {\n declare local var.config STRING;\n set var.config = get_sanitised_netacea_config_captcha_header();\n if (var.config ~ \"(?i)(?:^|&)\\s*name\\s*=\\s*(.*?)\\s*(?:&|$)\") {\n return re.group.1;\n }\n return \"\";\n}\nsub get_netacea_captcha_header_value STRING {\n declare local var.config STRING;\n set var.config = get_sanitised_netacea_config_captcha_header();\n if (var.config ~ \"(?i)(?:^|&)\\s*value\\s*=\\s*(.*?)\\s*(?:&|$)\") {\n return re.group.1;\n }\n return \"\";\n}\nsub is_path_ignored BOOL {\n declare local var.netacea_ignore_list STRING;\n declare local var.req_path STRING;\n set var.netacea_ignore_list = get_netacea_config_ignore_list();\n set var.req_path = urldecode(req.url.path);\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"\\s*(,\\s*)+\", \",\");\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"(^|,)\\s*/*\", \"\\1/\");\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"/*\\s*(,|$)\", \"\\1\");\n if (var.netacea_ignore_list ~ \"^([^,]+),*([^,]+)?,*([^,]+)?,*([^,]+)?,*([^,]+)?\") {\n if (re.group.1 && (var.req_path == urldecode(re.group.1) || std.prefixof(var.req_path, urldecode(re.group.1) + \"/\"))) {\n return true;\n }\n if (re.group.2 && (var.req_path == urldecode(re.group.2) || std.prefixof(var.req_path, urldecode(re.group.2) + \"/\"))) {\n return true;\n }\n if (re.group.3 && (var.req_path == urldecode(re.group.3) || std.prefixof(var.req_path, urldecode(re.group.3) + \"/\"))) {\n return true;\n }\n if (re.group.4 && (var.req_path == urldecode(re.group.4) || std.prefixof(var.req_path, urldecode(re.group.4) + \"/\"))) {\n return true;\n }\n if (re.group.5 && (var.req_path == urldecode(re.group.5) || std.prefixof(var.req_path, urldecode(re.group.5) + \"/\"))) {\n return true;\n }\n }\n return false;\n}\nsub netacea_should_return_json BOOL {\n declare local var.enable_captcha_content_negotiation STRING;\n set var.enable_captcha_content_negotiation = get_netacea_config_enable_captcha_content_negotiation();\n if (var.enable_captcha_content_negotiation != \"true\") {\n return false;\n }\n declare local var.html_weight FLOAT;\n declare local var.json_weight FLOAT;\n set var.html_weight = 0.0;\n set var.json_weight = 0.0;\n if (req.http.Accept ~ \"(?i)(^|,)\\s*application/json\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.json_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n } elseif (req.http.Accept ~ \"(?i)(^|,)\\s*application/\\*\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.json_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n }\n if (req.http.Accept ~ \"(?i)(^|,)\\s*text/html\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.html_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n } elseif (req.http.Accept ~ \"(^|,)\\s*text/\\*\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.html_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n }\n return var.json_weight > var.html_weight;\n}\nsub netacea_hide_response_headers {\n unset resp.http.X-Netacea-Captcha;\n unset resp.http.X-Netacea-Event-ID;\n unset resp.http.X-Netacea-Match;\n unset resp.http.X-Netacea-MitATA-Expiry;\n unset resp.http.X-Netacea-MitATA-Value;\n unset resp.http.X-Netacea-Mitigate;\n}\nsub set_netacea_captcha_header {\n declare local var.captcha_header_name STRING;\n declare local var.captcha_header_value STRING;\n set var.captcha_header_name = get_netacea_captcha_header_name();\n set var.captcha_header_value = get_netacea_captcha_header_value();\n if (var.captcha_header_name != \"\") {\n header.set(resp, var.captcha_header_name, var.captcha_header_value);\n }\n}\nsub set_netacea_ip_header {\n declare local var.ip_header_name STRING;\n set var.ip_header_name = get_netacea_config_real_ip_header_name();\n declare local var.ip_header_value STRING;\n set var.ip_header_value = if (std.strlen(var.ip_header_name) > 0, header.get(req, var.ip_header_name), \"\");\n set req.http.X-Netacea-Client-IP = if (std.strlen(var.ip_header_value) > 0, var.ip_header_value, client.ip);\n}\nsub set_netacea_cookies {\n if (req.http.netacea_set_cookies == \"1\") {\n declare local var.ignored BOOL;\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_encryption_key STRING;\n set var.ignored = setcookie.delete_by_name(resp, \"_mitata\");\n set var.ignored = setcookie.delete_by_name(resp, \"_mitatacaptcha\");\n declare local var.netacea_captcha_cookie_name STRING;\n set var.netacea_captcha_cookie_name = get_sanitised_netacea_config_captcha_cookie_name();\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n call set_mitata_cookie;\n if (req.http.netacea_mitata_captcha_cookie_value && req.http.netacea_mitata_captcha_cookie_expiry) {\n if (var.netacea_encryption_key ~ \".\") {\n declare local var.netacea_iv STRING;\n declare local var.netacea_iv_trimmed STRING;\n declare local var.netacea_sig STRING;\n declare local var.netacea_mitata_captcha_cookie_value_base64 STRING;\n declare local var.netacea_mitata_captcha_cookie_value_hex STRING;\n declare local var.netacea_mitata_captcha_cookie_value_encrypted STRING;\n declare local var.netacea_mitata_captcha_cookie_final_value STRING;\n set var.netacea_mitata_captcha_cookie_value_base64 = digest.base64(req.http.netacea_mitata_captcha_cookie_value);\n set var.netacea_mitata_captcha_cookie_value_hex = bin.base64_to_hex(var.netacea_mitata_captcha_cookie_value_base64);\n set var.netacea_iv = uuid.version4();\n set var.netacea_iv_trimmed = std.replaceall(var.netacea_iv, \"-\", \"\");\n set var.netacea_mitata_captcha_cookie_value_encrypted = crypto.encrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv_trimmed, var.netacea_mitata_captcha_cookie_value_hex);\n set var.netacea_sig = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_captcha_cookie_value_encrypted);\n set var.netacea_mitata_captcha_cookie_final_value = var.netacea_iv_trimmed + \".\" + var.netacea_mitata_captcha_cookie_value_encrypted + \".\" + var.netacea_sig;\n add resp.http.Set-Cookie = var.netacea_captcha_cookie_name + \"=\" + var.netacea_mitata_captcha_cookie_final_value + \"; Max-Age=\" + req.http.netacea_mitata_captcha_cookie_expiry + \"; Path=/;\";\n }\n if (var.netacea_encryption_key !~ \".\") {\n add resp.http.Set-Cookie = var.netacea_captcha_cookie_name + \"=\" + req.http.netacea_mitata_captcha_cookie_value + \"; Max-Age=\" + req.http.netacea_mitata_captcha_cookie_expiry + \"; Path=/;\";\n }\n }\n }\n}\nsub netacea_calculate_best_mitigation {\n if (!req.http.netacea_bctype_string) {\n declare local var.netacea_match STRING;\n declare local var.netacea_mitigate STRING;\n declare local var.netacea_captcha STRING;\n declare local var.netacea_match_string STRING;\n declare local var.netacea_mitigate_string STRING;\n declare local var.netacea_captcha_string STRING;\n declare local var.netacea_captcha_mitigate_string STRING;\n declare local var.netacea_best_mitigation STRING;\n declare local var.netacea_bctype_string STRING;\n if (resp.http.x-netacea-match) { \n set var.netacea_match = resp.http.x-netacea-match;\n } elseif (req.http.netacea_match) { \n set var.netacea_match = req.http.netacea_match;\n } else {\n set var.netacea_match = \"0\";\n }\n if (resp.http.x-netacea-mitigate) { \n set var.netacea_mitigate = resp.http.x-netacea-mitigate;\n } elseif (req.http.netacea_mitigate) { \n set var.netacea_mitigate = req.http.netacea_mitigate;\n } else {\n set var.netacea_mitigate = \"0\";\n }\n if (resp.http.x-netacea-captcha) { \n set var.netacea_captcha = resp.http.x-netacea-captcha;\n } elseif (req.http.netacea_captcha) { \n set var.netacea_captcha = req.http.netacea_captcha;\n } else {\n set var.netacea_captcha = \"0\";\n }\n if (var.netacea_match) {\n set var.netacea_match_string = table.lookup(Netacea_Match_Dict, var.netacea_match, \"unknown\");\n if (var.netacea_match_string != \"\") {\n set var.netacea_bctype_string = var.netacea_match_string + \"_\";\n }\n }\n if (var.netacea_mitigate) {\n set var.netacea_mitigate_string = table.lookup(Netacea_Mitigate_Dict, var.netacea_mitigate, \"unknown\");\n if (var.netacea_mitigate_string != \"\") {\n set var.netacea_bctype_string = var.netacea_bctype_string + var.netacea_mitigate_string;\n }\n set var.netacea_best_mitigation = table.lookup(Netacea_Best_Mitigations_Dict, var.netacea_mitigate, \"no-best-mitigation\");\n if (var.netacea_best_mitigation == \"no-best-mitigation\") {\n set var.netacea_best_mitigation = \"\";\n }\n }\n if (var.netacea_captcha) {\n if (req.url != \"/AtaVerifyCaptcha\") {\n if (var.netacea_captcha == \"2\") {\n set var.netacea_captcha = \"4\";\n } elseif (var.netacea_captcha == \"3\") {\n set var.netacea_captcha = \"5\";\n }\n }\n set var.netacea_captcha_string = table.lookup(Netacea_Captcha_Dict, var.netacea_captcha, \"unknown\");\n if (var.netacea_captcha_string != \"\") {\n set var.netacea_bctype_string = var.netacea_bctype_string + \",\" + var.netacea_captcha_string;\n }\n set var.netacea_captcha_mitigate_string = table.lookup(Netacea_Best_Mitigations_Captcha_Dict, var.netacea_captcha, \"no-best-captcha-mitigation\");\n if (var.netacea_captcha_mitigate_string != \"no-best-captcha-mitigation\") {\n set var.netacea_best_mitigation = var.netacea_captcha_mitigate_string;\n }\n }\n set req.http.netacea_bctype_string = var.netacea_bctype_string;\n set req.http.netacea_best_mitigation = var.netacea_best_mitigation;\n set req.http.netacea_best_mitigation_code = var.netacea_match + var.netacea_mitigate + var.netacea_captcha;\n if (var.netacea_mitigate == \"3\") {\n set req.http.netacea_require_revalidation = \"1\";\n }\n if (var.netacea_mitigate == \"1\" && var.netacea_captcha != \"2\" && var.netacea_captcha != \"4\") {\n set req.http.netacea_require_revalidation = \"1\";\n }\n }\n}\nsub set_mitata_cookie {\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_encryption_key STRING;\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n if (!req.http.X-Netacea-UserId) {\n set req.http.X-Netacea-UserId = \"c\" + randomstr(15, \"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\");\n set req.http.x-netacea:cookie_session_status = \"1\";\n }\n declare local var.netacea_iv STRING;\n declare local var.netacea_iv_trimmed STRING;\n declare local var.netacea_sig STRING;\n declare local var.netacea_mitata_cookie_full_value_base64 STRING;\n declare local var.netacea_mitata_cookie_full_value_hex STRING;\n declare local var.netacea_mitata_cookie_full_value_encrypted STRING;\n declare local var.netacea_mitata_cookie_final_value STRING;\n declare local var.netacea_mitata_cookie_full_value STRING;\n declare local var.netacea_ataCookie_stringValue STRING;\n declare local var.netacea_ataCookie_HMAC STRING;\n declare local var.netacea_mitSvc_exp STRING;\n declare local var.netacea_mitSvc_sig STRING;\n declare local var.netacea_mitSvc_userId STRING;\n declare local var.netacea_mitigation_code STRING;\n declare local var.netacea_client_ip_time_ua STRING;\n declare local var.netacea_client_ip_time_ua_hash STRING;\n declare local var.netacea_cookie_name STRING;\n set var.netacea_mitigation_code = req.http.netacea_best_mitigation_code;\n set var.netacea_mitSvc_userId = req.http.X-Netacea-UserId;\n set var.netacea_cookie_name = get_sanitised_netacea_config_cookie_name();\n if (req.http.netacea_require_revalidation == \"1\") {\n set var.netacea_mitSvc_exp = time.units(\"s\", time.sub(now, 1m));\n } else {\n set var.netacea_mitSvc_exp = time.units(\"s\", time.add(now, 1m));\n }\n set var.netacea_client_ip_time_ua = req.http.X-Netacea-Client-IP + \"|\" + var.netacea_mitSvc_exp + \"|\" + req.http.user-agent;\n set var.netacea_client_ip_time_ua_hash = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_client_ip_time_ua);\n if (var.netacea_client_ip_time_ua_hash ~ \"0x(.*)\") {\n set var.netacea_client_ip_time_ua_hash = re.group.1;\n }\n set var.netacea_ataCookie_stringValue = var.netacea_mitSvc_exp + \"_/@#/\" + var.netacea_mitSvc_userId + \"_/@#/\" + digest.base64(var.netacea_client_ip_time_ua_hash) + \"_/@#/\" + var.netacea_mitigation_code;\n set var.netacea_ataCookie_HMAC = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_ataCookie_stringValue);\n if (var.netacea_ataCookie_HMAC ~ \"0x(.*)\") {\n set var.netacea_ataCookie_HMAC = re.group.1;\n }\n set var.netacea_mitSvc_sig = digest.base64(var.netacea_ataCookie_HMAC);\n set var.netacea_mitata_cookie_full_value = var.netacea_mitSvc_sig + \"_/@#/\" + var.netacea_ataCookie_stringValue;\n if (var.netacea_encryption_key ~ \".\") {\n set var.netacea_mitata_cookie_full_value_base64 = digest.base64(var.netacea_mitata_cookie_full_value);\n set var.netacea_mitata_cookie_full_value_hex = bin.base64_to_hex(var.netacea_mitata_cookie_full_value_base64);\n set var.netacea_iv = uuid.version4();\n set var.netacea_iv_trimmed = std.replaceall(var.netacea_iv, \"-\", \"\");\n set var.netacea_mitata_cookie_full_value_encrypted = crypto.encrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv_trimmed, var.netacea_mitata_cookie_full_value_hex);\n set var.netacea_sig = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_cookie_full_value_encrypted);\n set var.netacea_mitata_cookie_final_value = var.netacea_iv_trimmed + \".\" + var.netacea_mitata_cookie_full_value_encrypted + \".\" + var.netacea_sig;\n add resp.http.Set-Cookie = var.netacea_cookie_name + \"=\" + var.netacea_mitata_cookie_final_value + \"; Max-Age=\" + time.units(\"s\", 1d) + \"; Path=/;\";\n }\n if (var.netacea_encryption_key !~ \".\") {\n add resp.http.Set-Cookie = var.netacea_cookie_name + \"=\" + var.netacea_mitata_cookie_full_value+ \"; Max-Age=\" + time.units(\"s\", 1d) + \"; Path=/;\";\n }\n set req.http.mitigation_user_id = var.netacea_mitSvc_userId;\n}\nsub process_netacea_mitata_cookie {\n declare local var.netacea_mitSvc_secret STRING;\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n declare local var.netacea_cookie_sig STRING;\n declare local var.netacea_cookie_payload STRING;\n declare local var.netacea_cookie_expiry STRING;\n declare local var.netacea_client_ip_time_ua_hash STRING;\n declare local var.netacea_real_client_ip_time_ua STRING;\n declare local var.netacea_real_client_ip_time_ua_hash STRING;\n declare local var.netacea_cookie_HMAC STRING;\n declare local var.netacea_cookie_real_value STRING;\n if (req.http.Cookie:_mitata) {\n if (req.http.Cookie:_mitata ~ \"^(.*)_\\/@#\\/((\\d+)_\\/@#\\/(.+)_\\/@#\\/(.+)_\\/@#\\/((\\d)(\\d)(\\d)))$\") {\n set var.netacea_cookie_sig = re.group.1;\n set var.netacea_cookie_payload = re.group.2;\n set var.netacea_cookie_expiry = re.group.3;\n set req.http.X-Netacea-UserId = re.group.4;\n set var.netacea_client_ip_time_ua_hash = re.group.5;\n set req.http.netacea_match = re.group.7;\n set req.http.netacea_mitigate = re.group.8;\n set req.http.netacea_captcha = re.group.9;\n set var.netacea_cookie_real_value = var.netacea_cookie_expiry + \"_/@#/\" + req.http.X-Netacea-UserId + \"_/@#/\" + var.netacea_client_ip_time_ua_hash + \"_/@#/\" + req.http.netacea_match + req.http.netacea_mitigate + req.http.netacea_captcha;\n set var.netacea_cookie_HMAC = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_cookie_real_value);\n if (var.netacea_cookie_HMAC ~ \"0x(.*)\") {\n set var.netacea_cookie_HMAC = re.group.1;\n }\n set var.netacea_real_client_ip_time_ua = req.http.X-Netacea-Client-IP + \"|\" + var.netacea_cookie_expiry + \"|\" + req.http.user-agent;\n set var.netacea_real_client_ip_time_ua_hash = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_real_client_ip_time_ua);\n if (var.netacea_real_client_ip_time_ua_hash ~ \"0x(.*)\") {\n set var.netacea_real_client_ip_time_ua_hash = re.group.1;\n }\n if (var.netacea_cookie_sig != digest.base64(var.netacea_cookie_HMAC)) {\n unset req.http.Cookie:_mitata;\n unset req.http.X-Netacea-UserId;\n unset req.http.netacea_match;\n unset req.http.netacea_mitigate;\n unset req.http.netacea_captcha;\n } else {\n if (time.is_after(now, std.time(var.netacea_cookie_expiry, now)) || digest.base64(var.netacea_real_client_ip_time_ua_hash) != var.netacea_client_ip_time_ua_hash ) {\n set req.http.netacea_mitata_must_reauthenticate = \"1\";\n set req.http.x-netacea:cookie_session_status = \"3\";\n } else {\n set req.http.x-netacea:cookie_session_status = \"2\";\n }\n }\n } else {\n unset req.http.Cookie:_mitata;\n }\n }\n if (!req.http.Cookie:_mitata) {\n unset req.http.Cookie:_mitatacaptcha;\n }\n}\nsub normalise_netacea_cookie_names {\n declare local var.netacea_custom_cookie_name STRING;\n declare local var.netacea_custom_captcha_cookie_name STRING;\n set var.netacea_custom_cookie_name = get_sanitised_netacea_config_cookie_name();\n set var.netacea_custom_captcha_cookie_name = get_sanitised_netacea_config_captcha_cookie_name();\n set req.http.Cookie = regsuball(req.http.Cookie, \";\\s*+\", \"; \");\n if (var.netacea_custom_cookie_name !~ \"^_mitata$\") {\n unset req.http.Cookie:_mitata;\n set req.http.Cookie = std.replace_prefix(req.http.Cookie, var.netacea_custom_cookie_name + \"=\", \"_mitata=\");\n set req.http.Cookie = std.replace(req.http.Cookie, \"; \" + var.netacea_custom_cookie_name + \"=\", \"; _mitata=\");\n }\n if (var.netacea_custom_captcha_cookie_name !~ \"^_mitatacaptcha$\") {\n unset req.http.Cookie:_mitatacaptcha;\n set req.http.Cookie = std.replace_prefix(req.http.Cookie, var.netacea_custom_captcha_cookie_name + \"=\", \"_mitatacaptcha=\");\n set req.http.Cookie = std.replace(req.http.Cookie, \"; \" + var.netacea_custom_captcha_cookie_name + \"=\", \"; _mitatacaptcha=\");\n }\n}\nsub decrypt_netacea_cookies_values {\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_mitata_cookie_encrypted STRING;\n declare local var.netacea_encryption_key STRING;\n declare local var.netacea_iv STRING;\n declare local var.netacea_mitata_cookie_base64 STRING;\n declare local var.netacea_mitata_cookie_hex STRING;\n declare local var.netacea_mitata_cookie_value STRING;\n declare local var.netacea_mitata_cookie_sig STRING;\n declare local var.netacea_mitata_captcha_cookie_encrypted STRING;\n declare local var.netacea_captcha_iv STRING;\n declare local var.netacea_mitata_captcha_cookie_base64 STRING;\n declare local var.netacea_mitata_captcha_cookie_hex STRING;\n declare local var.netacea_mitata_captcha_cookie_value STRING;\n declare local var.netacea_mitata_captcha_cookie_sig STRING;\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n if (var.netacea_encryption_key ~ \".\") {\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n if (req.http.Cookie:_mitata ~ \".\") {\n if (req.http.Cookie:_mitata ~ \"^(.*?)\\.\") {\n set var.netacea_iv = re.group.1;\n }\n if (req.http.Cookie:_mitata ~ \"\\.(.*?)\\.\") {\n set var.netacea_mitata_cookie_encrypted = re.group.1;\n }\n if (req.http.Cookie:_mitata ~ \"([^\\.]+$)\") {\n set var.netacea_mitata_cookie_sig = re.group.1;\n }\n set var.netacea_mitata_cookie_hex = crypto.decrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv, var.netacea_mitata_cookie_encrypted);\n set var.netacea_mitata_cookie_base64 = bin.hex_to_base64(var.netacea_mitata_cookie_hex);\n set var.netacea_mitata_cookie_value = digest.base64_decode(var.netacea_mitata_cookie_base64);\n set req.http.Cookie:_mitata = var.netacea_mitata_cookie_value;\n if(var.netacea_mitata_cookie_sig != digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_cookie_encrypted)) {\n unset req.http.Cookie:_mitata;\n }\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"^(.*?)\\.\") {\n if (req.http.Cookie:_mitatacaptcha ~ \"^(.*?)\\.\") {\n set var.netacea_captcha_iv = re.group.1;\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"\\.(.*?)\\.\") {\n set var.netacea_mitata_captcha_cookie_encrypted = re.group.1;\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"([^\\.]+$)\") {\n set var.netacea_mitata_captcha_cookie_sig = re.group.1;\n }\n set var.netacea_mitata_captcha_cookie_hex = crypto.decrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_captcha_iv, var.netacea_mitata_captcha_cookie_encrypted);\n set var.netacea_mitata_captcha_cookie_base64 = bin.hex_to_base64(var.netacea_mitata_captcha_cookie_hex);\n set var.netacea_mitata_captcha_cookie_value = digest.base64_decode(var.netacea_mitata_captcha_cookie_base64);\n set req.http.Cookie:_mitatacaptcha = var.netacea_mitata_captcha_cookie_value;\n if(var.netacea_mitata_captcha_cookie_sig != digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_captcha_cookie_encrypted)) {\n unset req.http.Cookie:_mitatacaptcha;\n }\n }\n }\n}\nsub cleanup_netacea_variables {\n if (fastly.ff.visits_this_service > 0) {\n return;\n }\n set req.http.netacea_best_mitigation_code = \"000\";\n set req.http.netacea_match = \"0\";\n set req.http.netacea_mitigate = \"0\";\n set req.http.netacea_captcha = \"0\";\n unset req.http.mit_status;\n unset req.http.netacea_bctype_string;\n unset req.http.netacea_best_mitigation;\n unset req.http.netacea_cookies;\n unset req.http.netacea_mitata_captcha_cookie_expiry;\n unset req.http.netacea_mitata_captcha_cookie_value;\n unset req.http.netacea_mitata_must_reauthenticate;\n unset req.http.netacea_require_revalidation;\n unset req.http.netacea_set_cookies;\n unset req.http.X-Netacea-Match;\n unset req.http.X-Netacea-Mitigate;\n unset req.http.X-Netacea-Captcha;\n unset req.http.X-Netacea-Event-ID;\n unset req.http.X-Netacea-Api-Key;\n unset req.http.X-Netacea-Captcha-Status;\n unset req.http.X-Netacea-UserId;\n unset req.http.X-Netacea-Compile-JSON;\n unset req.http.x-netacea;\n}\nsub netacea_check_req {\n if (req.is_purge) {\n return;\n }\n declare local var.netacea_mitSvc_authenticate BOOL;\n declare local var.netacea_mitSvc_apiKey STRING;\n declare local var.netacea_integration_mode STRING;\n declare local var.netacea_use_relative_path_captcha_assets STRING;\n declare local var.captcha_path STRING;\n set req.http.x-netacea:integration_mode = get_netacea_config_integration_mode();\n if (req.http.x-netacea:netacea_check_req_called || fastly.ff.visits_this_service > 0) {\n return;\n }\n set var.netacea_integration_mode = get_netacea_config_integration_mode();\n if (std.strlen(var.netacea_integration_mode) == 0) {\n return;\n }\n set req.http.x-netacea:netacea_check_req_called = \"true\";\n unset req.http.netacea_processed;\n if (is_path_ignored()) {\n return;\n }\n set var.netacea_mitSvc_apiKey = get_netacea_config_api_key();\n set var.netacea_use_relative_path_captcha_assets = get_netacea_config_use_relative_path_captcha_assets();\n set var.captcha_path = get_netacea_captcha_path();\n if (var.netacea_use_relative_path_captcha_assets == \"true\") {\n if (std.prefixof(req.url.path, \"/Mitigations/\") && req.method == \"GET\") {\n if (std.suffixof(req.url.path, \".css\") || std.suffixof(req.url.path, \".js\")) {\n set req.backend = F_CaptchaAssets;\n return(lookup);\n }\n }\n }\n if (var.captcha_path != \"\" && urldecode(req.url.path) == var.captcha_path) {\n set req.backend = F_MitSvc;\n set req.http.x-netacea:mit_svc_start_time = time.elapsed.msec;\n if (req.backend.healthy) {\n set req.http.netacea_origin_method = \"GET\";\n set req.http.netacea_processed = \"1\";\n set req.http.netacea_captcha_path = \"1\";\n set req.http.netacea_origin_host = req.http.host;\n set req.http.netacea_origin_url = req.url;\n set req.url = \"/captcha?\" + req.url.qs;\n set req.http.X-Netacea-Api-Key = var.netacea_mitSvc_apiKey;\n return(lookup);\n }\n }\n if (req.restarts == 0) {\n call set_netacea_ip_header;\n if (var.netacea_integration_mode != \"BYPASS\") {\n set var.netacea_mitSvc_authenticate = true;\n call normalise_netacea_cookie_names;\n call decrypt_netacea_cookies_values;\n call process_netacea_mitata_cookie;\n }\n } else {\n if (req.http.X-Netacea-Compile-JSON == \"requested\") {\n set req.http.netacea_processed = \"1\";\n set req.http.X-Netacea-Compile-JSON = \"processing\";\n error 601;\n }\n if (var.netacea_integration_mode == \"MITIGATE\" && req.http.netacea_best_mitigation == \"block\") {\n error 403;\n }\n }\n if (req.http.Cookie:_mitata && !req.http.netacea_mitata_must_reauthenticate) {\n set var.netacea_mitSvc_authenticate = false;\n set req.http.x-netacea:cookie_session_status = \"2\";\n }\n set req.http.mitigation_user_id = req.http.X-Netacea-UserId;\n set req.http.integration_type = get_netacea_config_integration_type();\n set req.http.integration_version = get_netacea_config_integration_version();\n if (var.netacea_mitSvc_authenticate) {\n set req.http.netacea_set_cookies = \"1\";\n } else {\n if (var.netacea_integration_mode == \"INJECT\" && req.restarts == 0) {\n set req.http.X-Netacea-Match = req.http.netacea_match;\n set req.http.X-Netacea-Mitigate = req.http.netacea_mitigate;\n set req.http.X-Netacea-Captcha = req.http.netacea_captcha;\n }\n }\n if (var.netacea_integration_mode ~ \"(MITIGATE|INJECT)\" && var.netacea_mitSvc_authenticate) {\n set req.backend = F_MitSvc;\n set req.http.x-netacea:mit_svc_start_time = time.elapsed.msec;\n if (req.backend.healthy) {\n unset req.http.netacea_match;\n unset req.http.netacea_mitigate;\n unset req.http.netacea_captcha;\n unset req.http.Cookie:_mitata;\n set req.http.netacea_origin_method = req.method;\n set req.http.netacea_processed = \"1\";\n set req.http.netacea_origin_host = req.http.host;\n set req.http.netacea_origin_url = req.url;\n if (req.url != \"/AtaVerifyCaptcha\") {\n set req.method = \"GET\";\n set req.url = \"/\";\n }\n set req.http.X-Netacea-Api-Key = var.netacea_mitSvc_apiKey;\n return(pass);\n }\n }\n}\n", + "template": "backend F_MitSvc {\n .between_bytes_timeout = 100ms;\n .connect_timeout = 500ms;\n .dynamic = true;\n .first_byte_timeout = 500ms;\n .host = \"mitigations-lbr.netacea.net\";\n .max_connections = 200;\n .port = \"443\";\n .share_key = \"NetaceaProtectorAPI\";\n .host_header = \"mitigations-lbr.netacea.net\";\n .always_use_host_header = true;\n .ssl = true;\n .ssl_cert_hostname = \"mitigations-lbr.netacea.net\";\n .ssl_check_cert = always;\n .ssl_sni_hostname = \"mitigations-lbr.netacea.net\";\n .probe = {\n .dummy = false;\n .initial = 5;\n .request = \"GET /_health HTTP/1.1\" \"Host: mitigations-lbr.netacea.net\" \"Connection: close\" \"User-Agent: Varnish/fastly (healthcheck)\";\n .threshold = 1;\n .timeout = 2s;\n .window = 5;\n .expected_response = 200;\n }\n}\nbackend F_CaptchaAssets {\n .between_bytes_timeout = 10s;\n .connect_timeout = 1s;\n .dynamic = true;\n .first_byte_timeout = 15s;\n .host = \"assets.ntcacdn.net\";\n .max_connections = 200;\n .port = \"443\";\n .share_key = \"4nxXnE6VkrJiVuGz4G1VbJ\";\n .host_header = \"assets.ntcacdn.net\";\n .always_use_host_header = true;\n .ssl = true;\n .ssl_cert_hostname = \"assets.ntcacdn.net\";\n .ssl_check_cert = always;\n .ssl_sni_hostname = \"assets.ntcacdn.net\";\n .probe = {\n .dummy = true;\n .initial = 5;\n .request = \"HEAD / HTTP/1.1\" \"Host: assets.ntcacdn.net\" \"Connection: close\";\n .threshold = 1;\n .timeout = 2s;\n .window = 5;\n }\n}\n\ntable Netacea_Config {\n \"integration_mode\": \"{{netacea_integration_mode}}\",\n \"api_key\": \"{{netacea_api_key}}\",\n \"secret_key\": \"{{netacea_secret}}\",\n \"encryption_key\": \"{{netacea_encryption_key}}\",\n \"cookie_name\": \"{{netacea_cookie_name}}\",\n \"captcha_cookie_name\": \"{{netacea_captcha_cookie_name}}\",\n \"ignore_list\": \"{{netacea_ignore_list}}\",\n \"use_relative_path_captcha_assets\": \"{{netacea_use_relative_path_captcha_assets}}\",\n \"real_ip_header_name\": \"{{netacea_real_ip_header_name}}\",\n \"captcha_path\": \"{{netacea_captcha_path}}\",\n \"captcha_header\": \"{{netacea_captcha_header}}\",\n \"enable_captcha_content_negotiation\": \"{{netacea_enable_ccn}}\"\n}\nsub get_netacea_config_integration_type STRING {\n return \"fastly/magento\";\n}\nsub get_netacea_config_integration_version STRING {\n return \"5.10.6\";\n}\nsub get_netacea_config_api_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"api_key\");\n }\n return table.lookup(Netacea_Config, \"api_key\", \"\");\n}\nsub get_netacea_config_secret_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"secret_key\");\n }\n return table.lookup(Netacea_Config, \"secret_key\", \"\");\n}\nsub get_netacea_config_encryption_key STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"encryption_key\");\n }\n return table.lookup(Netacea_Config, \"encryption_key\", \"\");\n}\nsub get_netacea_config_integration_mode STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"integration_mode\");\n }\n return table.lookup(Netacea_Config, \"integration_mode\", \"\");\n}\nsub get_netacea_config_ignore_list STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"ignore_list\");\n }\n return table.lookup(Netacea_Config, \"ignore_list\", \"\");\n}\nsub get_netacea_config_cookie_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"cookie_name\");\n }\n return table.lookup(Netacea_Config, \"cookie_name\", \"\");\n}\nsub get_netacea_config_captcha_cookie_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_cookie_name\");\n }\n return table.lookup(Netacea_Config, \"captcha_cookie_name\", \"\");\n}\nsub get_netacea_config_use_relative_path_captcha_assets STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"use_relative_path_captcha_assets\");\n }\n return table.lookup(Netacea_Config, \"use_relative_path_captcha_assets\", \"\");\n}\nsub get_netacea_config_real_ip_header_name STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"real_ip_header_name\");\n }\n return table.lookup(Netacea_Config, \"real_ip_header_name\", \"\");\n}\nsub get_netacea_config_captcha_path STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_path\");\n }\n return table.lookup(Netacea_Config, \"captcha_path\", \"\");\n}\nsub get_netacea_config_captcha_header STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"captcha_header\");\n }\n return table.lookup(Netacea_Config, \"captcha_header\", \"\");\n}\nsub get_netacea_config_enable_captcha_content_negotiation STRING {\n if (req.http.x-netacea:edge_config_key_prefix) {\n return table.lookup(netacea_edge_config, req.http.x-netacea:edge_config_key_prefix + \"enable_captcha_content_negotiation\");\n }\n return table.lookup(Netacea_Config, \"enable_captcha_content_negotiation\", \"\");\n}\nsub get_sanitised_netacea_config_cookie_name STRING {\n declare local var.name STRING;\n set var.name = get_netacea_config_cookie_name();\n if (var.name ~ \"^\\s*(.*?)\\s*$\") {\n if (re.group.1 != \"\") {\n return re.group.1;\n }\n }\n return \"_mitata\";\n}\nsub get_sanitised_netacea_config_captcha_cookie_name STRING {\n declare local var.name STRING;\n set var.name = get_netacea_config_captcha_cookie_name();\n if (var.name ~ \"^\\s*(.*?)\\s*$\") {\n if (re.group.1 != \"\") {\n return re.group.1;\n }\n }\n return \"_mitatacaptcha\";\n}\ntable Netacea_Match_Dict {\n \"0\": \"\",\n \"1\": \"ua\",\n \"2\": \"ip\",\n \"3\": \"visitor\",\n \"4\": \"datacenter\",\n \"5\": \"customer_session\",\n \"6\": \"organisation\",\n \"7\": \"asn\",\n \"8\": \"country\",\n \"9\": \"combination\"\n}\ntable Netacea_Mitigate_Dict {\n \"0\": \"\",\n \"1\": \"blocked\",\n \"2\": \"allow\",\n \"3\": \"hardblocked\"\n}\ntable Netacea_Best_Mitigations_Dict {\n \"0\": \"\",\n \"1\": \"block\",\n \"2\": \"allow\",\n \"3\": \"block\"\n}\ntable Netacea_Best_Mitigations_Captcha_Dict {\n \"1\": \"captcha\",\n \"2\": \"\",\n \"3\": \"captcha\",\n \"4\": \"\",\n \"5\": \"captcha\"\n}\ntable Netacea_Captcha_Dict {\n \"0\": \"\",\n \"1\": \"captcha_serve\",\n \"2\": \"captcha_pass\",\n \"3\": \"captcha_fail\",\n \"4\": \"captcha_cookiepass\",\n \"5\": \"captcha_cookiefail\",\n}\nsub check_secret_key BOOL {\n declare local var.netacea_mitSvc_secret STRING;\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n if (std.strlen(var.netacea_mitSvc_secret) <= 0) {\n return false;\n }\n return true;\n}\nsub get_netacea_captcha_path STRING {\n declare local var.path STRING;\n set var.path = get_netacea_config_captcha_path();\n set var.path = regsub(var.path, \"^\\s*/*\", \"/\");\n set var.path = regsub(var.path, \"\\s*$\", \"\");\n return urldecode(var.path);\n}\nsub get_netacea_integration_mode STRING {\n declare local var.netacea_integration_mode STRING;\n set var.netacea_integration_mode = get_netacea_config_integration_mode();\n if (var.netacea_integration_mode == \"\") {\n return \"\";\n } else {\n if (check_secret_key()) {\n return var.netacea_integration_mode;\n } else {\n return \"BYPASS\";\n }\n }\n}\nsub get_sanitised_netacea_config_captcha_header STRING {\n declare local var.value STRING;\n set var.value = get_netacea_config_captcha_header();\n set var.value = urldecode(regsuball(var.value, \"&#x(.{2});\", \"%25\\1\"));\n set var.value = std.replaceall(var.value, \""\", \"%22\");\n set var.value = std.replaceall(var.value, \"<\", \"<\");\n set var.value = std.replaceall(var.value, \">\", \">\");\n set var.value = std.replaceall(var.value, \"&\", \"&\");\n return var.value;\n}\nsub get_netacea_captcha_header_name STRING {\n declare local var.config STRING;\n set var.config = get_sanitised_netacea_config_captcha_header();\n if (var.config ~ \"(?i)(?:^|&)\\s*name\\s*=\\s*(.*?)\\s*(?:&|$)\") {\n return re.group.1;\n }\n return \"\";\n}\nsub get_netacea_captcha_header_value STRING {\n declare local var.config STRING;\n set var.config = get_sanitised_netacea_config_captcha_header();\n if (var.config ~ \"(?i)(?:^|&)\\s*value\\s*=\\s*(.*?)\\s*(?:&|$)\") {\n return re.group.1;\n }\n return \"\";\n}\nsub is_path_ignored BOOL {\n declare local var.netacea_ignore_list STRING;\n declare local var.req_path STRING;\n set var.netacea_ignore_list = get_netacea_config_ignore_list();\n set var.req_path = urldecode(req.url.path);\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"\\s*(,\\s*)+\", \",\");\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"(^|,)\\s*/*\", \"\\1/\");\n set var.netacea_ignore_list = regsuball(var.netacea_ignore_list, \"/*\\s*(,|$)\", \"\\1\");\n if (var.netacea_ignore_list ~ \"^([^,]+),*([^,]+)?,*([^,]+)?,*([^,]+)?,*([^,]+)?\") {\n if (re.group.1 && (var.req_path == urldecode(re.group.1) || std.prefixof(var.req_path, urldecode(re.group.1) + \"/\"))) {\n return true;\n }\n if (re.group.2 && (var.req_path == urldecode(re.group.2) || std.prefixof(var.req_path, urldecode(re.group.2) + \"/\"))) {\n return true;\n }\n if (re.group.3 && (var.req_path == urldecode(re.group.3) || std.prefixof(var.req_path, urldecode(re.group.3) + \"/\"))) {\n return true;\n }\n if (re.group.4 && (var.req_path == urldecode(re.group.4) || std.prefixof(var.req_path, urldecode(re.group.4) + \"/\"))) {\n return true;\n }\n if (re.group.5 && (var.req_path == urldecode(re.group.5) || std.prefixof(var.req_path, urldecode(re.group.5) + \"/\"))) {\n return true;\n }\n }\n return false;\n}\nsub netacea_should_return_json BOOL {\n declare local var.enable_captcha_content_negotiation STRING;\n set var.enable_captcha_content_negotiation = get_netacea_config_enable_captcha_content_negotiation();\n if (var.enable_captcha_content_negotiation != \"true\") {\n return false;\n }\n declare local var.html_weight FLOAT;\n declare local var.json_weight FLOAT;\n set var.html_weight = 0.0;\n set var.json_weight = 0.0;\n if (req.http.Accept ~ \"(?i)(^|,)\\s*application/json\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.json_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n } elseif (req.http.Accept ~ \"(?i)(^|,)\\s*application/\\*\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.json_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n }\n if (req.http.Accept ~ \"(?i)(^|,)\\s*text/html\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.html_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n } elseif (req.http.Accept ~ \"(^|,)\\s*text/\\*\\s*(;\\s*q\\s*=\\s*(\\d*(\\.\\d+)?|\\d+\\.)\\s*)?(,|$)\") {\n set var.html_weight = std.atof(if(re.group.3, re.group.3, \"1.0\"));\n }\n return var.json_weight > var.html_weight;\n}\nsub netacea_hide_response_headers {\n unset resp.http.X-Netacea-Captcha;\n unset resp.http.X-Netacea-Event-ID;\n unset resp.http.X-Netacea-Match;\n unset resp.http.X-Netacea-MitATA-Expiry;\n unset resp.http.X-Netacea-MitATA-Value;\n unset resp.http.X-Netacea-Mitigate;\n}\nsub set_netacea_captcha_header {\n declare local var.captcha_header_name STRING;\n declare local var.captcha_header_value STRING;\n set var.captcha_header_name = get_netacea_captcha_header_name();\n set var.captcha_header_value = get_netacea_captcha_header_value();\n if (var.captcha_header_name != \"\") {\n header.set(resp, var.captcha_header_name, var.captcha_header_value);\n }\n}\nsub set_netacea_ip_header {\n declare local var.ip_header_name STRING;\n set var.ip_header_name = get_netacea_config_real_ip_header_name();\n declare local var.ip_header_value STRING;\n set var.ip_header_value = if (std.strlen(var.ip_header_name) > 0, header.get(req, var.ip_header_name), \"\");\n set req.http.X-Netacea-Client-IP = if (std.strlen(var.ip_header_value) > 0, var.ip_header_value, client.ip);\n}\nsub set_netacea_cookies {\n if (req.http.netacea_set_cookies == \"1\") {\n declare local var.ignored BOOL;\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_encryption_key STRING;\n set var.ignored = setcookie.delete_by_name(resp, \"_mitata\");\n set var.ignored = setcookie.delete_by_name(resp, \"_mitatacaptcha\");\n declare local var.netacea_captcha_cookie_name STRING;\n set var.netacea_captcha_cookie_name = get_sanitised_netacea_config_captcha_cookie_name();\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n call set_mitata_cookie;\n if (req.http.netacea_mitata_captcha_cookie_value && req.http.netacea_mitata_captcha_cookie_expiry) {\n if (var.netacea_encryption_key ~ \".\") {\n declare local var.netacea_iv STRING;\n declare local var.netacea_iv_trimmed STRING;\n declare local var.netacea_sig STRING;\n declare local var.netacea_mitata_captcha_cookie_value_base64 STRING;\n declare local var.netacea_mitata_captcha_cookie_value_hex STRING;\n declare local var.netacea_mitata_captcha_cookie_value_encrypted STRING;\n declare local var.netacea_mitata_captcha_cookie_final_value STRING;\n set var.netacea_mitata_captcha_cookie_value_base64 = digest.base64(req.http.netacea_mitata_captcha_cookie_value);\n set var.netacea_mitata_captcha_cookie_value_hex = bin.base64_to_hex(var.netacea_mitata_captcha_cookie_value_base64);\n set var.netacea_iv = uuid.version4();\n set var.netacea_iv_trimmed = std.replaceall(var.netacea_iv, \"-\", \"\");\n set var.netacea_mitata_captcha_cookie_value_encrypted = crypto.encrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv_trimmed, var.netacea_mitata_captcha_cookie_value_hex);\n set var.netacea_sig = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_captcha_cookie_value_encrypted);\n set var.netacea_mitata_captcha_cookie_final_value = var.netacea_iv_trimmed + \".\" + var.netacea_mitata_captcha_cookie_value_encrypted + \".\" + var.netacea_sig;\n add resp.http.Set-Cookie = var.netacea_captcha_cookie_name + \"=\" + var.netacea_mitata_captcha_cookie_final_value + \"; Max-Age=\" + req.http.netacea_mitata_captcha_cookie_expiry + \"; Path=/;\";\n }\n if (var.netacea_encryption_key !~ \".\") {\n add resp.http.Set-Cookie = var.netacea_captcha_cookie_name + \"=\" + req.http.netacea_mitata_captcha_cookie_value + \"; Max-Age=\" + req.http.netacea_mitata_captcha_cookie_expiry + \"; Path=/;\";\n }\n }\n }\n}\nsub netacea_calculate_best_mitigation {\n if (!req.http.netacea_bctype_string) {\n declare local var.netacea_match STRING;\n declare local var.netacea_mitigate STRING;\n declare local var.netacea_captcha STRING;\n declare local var.netacea_match_string STRING;\n declare local var.netacea_mitigate_string STRING;\n declare local var.netacea_captcha_string STRING;\n declare local var.netacea_captcha_mitigate_string STRING;\n declare local var.netacea_best_mitigation STRING;\n declare local var.netacea_bctype_string STRING;\n if (resp.http.x-netacea-match) { \n set var.netacea_match = resp.http.x-netacea-match;\n } elseif (req.http.netacea_match) { \n set var.netacea_match = req.http.netacea_match;\n } else {\n set var.netacea_match = \"0\";\n }\n if (resp.http.x-netacea-mitigate) { \n set var.netacea_mitigate = resp.http.x-netacea-mitigate;\n } elseif (req.http.netacea_mitigate) { \n set var.netacea_mitigate = req.http.netacea_mitigate;\n } else {\n set var.netacea_mitigate = \"0\";\n }\n if (resp.http.x-netacea-captcha) { \n set var.netacea_captcha = resp.http.x-netacea-captcha;\n } elseif (req.http.netacea_captcha) { \n set var.netacea_captcha = req.http.netacea_captcha;\n } else {\n set var.netacea_captcha = \"0\";\n }\n if (var.netacea_match) {\n set var.netacea_match_string = table.lookup(Netacea_Match_Dict, var.netacea_match, \"unknown\");\n if (var.netacea_match_string != \"\") {\n set var.netacea_bctype_string = var.netacea_match_string + \"_\";\n }\n }\n if (var.netacea_mitigate) {\n set var.netacea_mitigate_string = table.lookup(Netacea_Mitigate_Dict, var.netacea_mitigate, \"unknown\");\n if (var.netacea_mitigate_string != \"\") {\n set var.netacea_bctype_string = var.netacea_bctype_string + var.netacea_mitigate_string;\n }\n set var.netacea_best_mitigation = table.lookup(Netacea_Best_Mitigations_Dict, var.netacea_mitigate, \"no-best-mitigation\");\n if (var.netacea_best_mitigation == \"no-best-mitigation\") {\n set var.netacea_best_mitigation = \"\";\n }\n }\n if (var.netacea_captcha) {\n if (req.url != \"/AtaVerifyCaptcha\") {\n if (var.netacea_captcha == \"2\") {\n set var.netacea_captcha = \"4\";\n } elseif (var.netacea_captcha == \"3\") {\n set var.netacea_captcha = \"5\";\n }\n }\n set var.netacea_captcha_string = table.lookup(Netacea_Captcha_Dict, var.netacea_captcha, \"unknown\");\n if (var.netacea_captcha_string != \"\") {\n set var.netacea_bctype_string = var.netacea_bctype_string + \",\" + var.netacea_captcha_string;\n }\n set var.netacea_captcha_mitigate_string = table.lookup(Netacea_Best_Mitigations_Captcha_Dict, var.netacea_captcha, \"no-best-captcha-mitigation\");\n if (var.netacea_captcha_mitigate_string != \"no-best-captcha-mitigation\") {\n set var.netacea_best_mitigation = var.netacea_captcha_mitigate_string;\n }\n }\n set req.http.netacea_bctype_string = var.netacea_bctype_string;\n set req.http.netacea_best_mitigation = var.netacea_best_mitigation;\n set req.http.netacea_best_mitigation_code = var.netacea_match + var.netacea_mitigate + var.netacea_captcha;\n if (var.netacea_mitigate == \"3\") {\n set req.http.netacea_require_revalidation = \"1\";\n }\n if (var.netacea_mitigate == \"1\" && var.netacea_captcha != \"2\" && var.netacea_captcha != \"4\") {\n set req.http.netacea_require_revalidation = \"1\";\n }\n }\n}\nsub set_mitata_cookie {\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_encryption_key STRING;\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n if (!req.http.X-Netacea-UserId) {\n set req.http.X-Netacea-UserId = \"c\" + randomstr(15, \"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\");\n set req.http.x-netacea:cookie_session_status = \"1\";\n }\n declare local var.netacea_iv STRING;\n declare local var.netacea_iv_trimmed STRING;\n declare local var.netacea_sig STRING;\n declare local var.netacea_mitata_cookie_full_value_base64 STRING;\n declare local var.netacea_mitata_cookie_full_value_hex STRING;\n declare local var.netacea_mitata_cookie_full_value_encrypted STRING;\n declare local var.netacea_mitata_cookie_final_value STRING;\n declare local var.netacea_mitata_cookie_full_value STRING;\n declare local var.netacea_ataCookie_stringValue STRING;\n declare local var.netacea_ataCookie_HMAC STRING;\n declare local var.netacea_mitSvc_exp STRING;\n declare local var.netacea_mitSvc_sig STRING;\n declare local var.netacea_mitSvc_userId STRING;\n declare local var.netacea_mitigation_code STRING;\n declare local var.netacea_client_ip_time_ua STRING;\n declare local var.netacea_client_ip_time_ua_hash STRING;\n declare local var.netacea_cookie_name STRING;\n set var.netacea_mitigation_code = req.http.netacea_best_mitigation_code;\n set var.netacea_mitSvc_userId = req.http.X-Netacea-UserId;\n set var.netacea_cookie_name = get_sanitised_netacea_config_cookie_name();\n if (req.http.netacea_require_revalidation == \"1\") {\n set var.netacea_mitSvc_exp = time.units(\"s\", time.sub(now, 1m));\n } else {\n set var.netacea_mitSvc_exp = time.units(\"s\", time.add(now, 1m));\n }\n set var.netacea_client_ip_time_ua = req.http.X-Netacea-Client-IP + \"|\" + var.netacea_mitSvc_exp + \"|\" + req.http.user-agent;\n set var.netacea_client_ip_time_ua_hash = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_client_ip_time_ua);\n if (var.netacea_client_ip_time_ua_hash ~ \"0x(.*)\") {\n set var.netacea_client_ip_time_ua_hash = re.group.1;\n }\n set var.netacea_ataCookie_stringValue = var.netacea_mitSvc_exp + \"_/@#/\" + var.netacea_mitSvc_userId + \"_/@#/\" + digest.base64(var.netacea_client_ip_time_ua_hash) + \"_/@#/\" + var.netacea_mitigation_code;\n set var.netacea_ataCookie_HMAC = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_ataCookie_stringValue);\n if (var.netacea_ataCookie_HMAC ~ \"0x(.*)\") {\n set var.netacea_ataCookie_HMAC = re.group.1;\n }\n set var.netacea_mitSvc_sig = digest.base64(var.netacea_ataCookie_HMAC);\n set var.netacea_mitata_cookie_full_value = var.netacea_mitSvc_sig + \"_/@#/\" + var.netacea_ataCookie_stringValue;\n if (var.netacea_encryption_key ~ \".\") {\n set var.netacea_mitata_cookie_full_value_base64 = digest.base64(var.netacea_mitata_cookie_full_value);\n set var.netacea_mitata_cookie_full_value_hex = bin.base64_to_hex(var.netacea_mitata_cookie_full_value_base64);\n set var.netacea_iv = uuid.version4();\n set var.netacea_iv_trimmed = std.replaceall(var.netacea_iv, \"-\", \"\");\n set var.netacea_mitata_cookie_full_value_encrypted = crypto.encrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv_trimmed, var.netacea_mitata_cookie_full_value_hex);\n set var.netacea_sig = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_cookie_full_value_encrypted);\n set var.netacea_mitata_cookie_final_value = var.netacea_iv_trimmed + \".\" + var.netacea_mitata_cookie_full_value_encrypted + \".\" + var.netacea_sig;\n add resp.http.Set-Cookie = var.netacea_cookie_name + \"=\" + var.netacea_mitata_cookie_final_value + \"; Max-Age=\" + time.units(\"s\", 1d) + \"; Path=/;\";\n }\n if (var.netacea_encryption_key !~ \".\") {\n add resp.http.Set-Cookie = var.netacea_cookie_name + \"=\" + var.netacea_mitata_cookie_full_value+ \"; Max-Age=\" + time.units(\"s\", 1d) + \"; Path=/;\";\n }\n set req.http.mitigation_user_id = var.netacea_mitSvc_userId;\n}\nsub process_netacea_mitata_cookie {\n declare local var.netacea_mitSvc_secret STRING;\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n declare local var.netacea_cookie_sig STRING;\n declare local var.netacea_cookie_payload STRING;\n declare local var.netacea_cookie_expiry STRING;\n declare local var.netacea_client_ip_time_ua_hash STRING;\n declare local var.netacea_real_client_ip_time_ua STRING;\n declare local var.netacea_real_client_ip_time_ua_hash STRING;\n declare local var.netacea_cookie_HMAC STRING;\n declare local var.netacea_cookie_real_value STRING;\n if (req.http.Cookie:_mitata) {\n if (req.http.Cookie:_mitata ~ \"^(.*)_\\/@#\\/((\\d+)_\\/@#\\/(.+)_\\/@#\\/(.+)_\\/@#\\/((\\d)(\\d)(\\d)))$\") {\n set var.netacea_cookie_sig = re.group.1;\n set var.netacea_cookie_payload = re.group.2;\n set var.netacea_cookie_expiry = re.group.3;\n set req.http.X-Netacea-UserId = re.group.4;\n set var.netacea_client_ip_time_ua_hash = re.group.5;\n set req.http.netacea_match = re.group.7;\n set req.http.netacea_mitigate = re.group.8;\n set req.http.netacea_captcha = re.group.9;\n set var.netacea_cookie_real_value = var.netacea_cookie_expiry + \"_/@#/\" + req.http.X-Netacea-UserId + \"_/@#/\" + var.netacea_client_ip_time_ua_hash + \"_/@#/\" + req.http.netacea_match + req.http.netacea_mitigate + req.http.netacea_captcha;\n set var.netacea_cookie_HMAC = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_cookie_real_value);\n if (var.netacea_cookie_HMAC ~ \"0x(.*)\") {\n set var.netacea_cookie_HMAC = re.group.1;\n }\n set var.netacea_real_client_ip_time_ua = req.http.X-Netacea-Client-IP + \"|\" + var.netacea_cookie_expiry + \"|\" + req.http.user-agent;\n set var.netacea_real_client_ip_time_ua_hash = digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_real_client_ip_time_ua);\n if (var.netacea_real_client_ip_time_ua_hash ~ \"0x(.*)\") {\n set var.netacea_real_client_ip_time_ua_hash = re.group.1;\n }\n if (var.netacea_cookie_sig != digest.base64(var.netacea_cookie_HMAC)) {\n unset req.http.Cookie:_mitata;\n unset req.http.X-Netacea-UserId;\n unset req.http.netacea_match;\n unset req.http.netacea_mitigate;\n unset req.http.netacea_captcha;\n } else {\n if (time.is_after(now, std.time(var.netacea_cookie_expiry, now)) || digest.base64(var.netacea_real_client_ip_time_ua_hash) != var.netacea_client_ip_time_ua_hash ) {\n set req.http.netacea_mitata_must_reauthenticate = \"1\";\n set req.http.x-netacea:cookie_session_status = \"3\";\n } else {\n set req.http.x-netacea:cookie_session_status = \"2\";\n }\n }\n } else {\n unset req.http.Cookie:_mitata;\n }\n }\n if (!req.http.Cookie:_mitata) {\n unset req.http.Cookie:_mitatacaptcha;\n }\n}\nsub normalise_netacea_cookie_names {\n declare local var.netacea_custom_cookie_name STRING;\n declare local var.netacea_custom_captcha_cookie_name STRING;\n set var.netacea_custom_cookie_name = get_sanitised_netacea_config_cookie_name();\n set var.netacea_custom_captcha_cookie_name = get_sanitised_netacea_config_captcha_cookie_name();\n set req.http.Cookie = regsuball(req.http.Cookie, \";\\s*+\", \"; \");\n if (var.netacea_custom_cookie_name !~ \"^_mitata$\") {\n unset req.http.Cookie:_mitata;\n set req.http.Cookie = std.replace_prefix(req.http.Cookie, var.netacea_custom_cookie_name + \"=\", \"_mitata=\");\n set req.http.Cookie = std.replace(req.http.Cookie, \"; \" + var.netacea_custom_cookie_name + \"=\", \"; _mitata=\");\n }\n if (var.netacea_custom_captcha_cookie_name !~ \"^_mitatacaptcha$\") {\n unset req.http.Cookie:_mitatacaptcha;\n set req.http.Cookie = std.replace_prefix(req.http.Cookie, var.netacea_custom_captcha_cookie_name + \"=\", \"_mitatacaptcha=\");\n set req.http.Cookie = std.replace(req.http.Cookie, \"; \" + var.netacea_custom_captcha_cookie_name + \"=\", \"; _mitatacaptcha=\");\n }\n}\nsub decrypt_netacea_cookies_values {\n declare local var.netacea_mitSvc_secret STRING;\n declare local var.netacea_mitata_cookie_encrypted STRING;\n declare local var.netacea_encryption_key STRING;\n declare local var.netacea_iv STRING;\n declare local var.netacea_mitata_cookie_base64 STRING;\n declare local var.netacea_mitata_cookie_hex STRING;\n declare local var.netacea_mitata_cookie_value STRING;\n declare local var.netacea_mitata_cookie_sig STRING;\n declare local var.netacea_mitata_captcha_cookie_encrypted STRING;\n declare local var.netacea_captcha_iv STRING;\n declare local var.netacea_mitata_captcha_cookie_base64 STRING;\n declare local var.netacea_mitata_captcha_cookie_hex STRING;\n declare local var.netacea_mitata_captcha_cookie_value STRING;\n declare local var.netacea_mitata_captcha_cookie_sig STRING;\n set var.netacea_encryption_key = get_netacea_config_encryption_key();\n if (var.netacea_encryption_key ~ \".\") {\n set var.netacea_mitSvc_secret = get_netacea_config_secret_key();\n if (req.http.Cookie:_mitata ~ \".\") {\n if (req.http.Cookie:_mitata ~ \"^(.*?)\\.\") {\n set var.netacea_iv = re.group.1;\n }\n if (req.http.Cookie:_mitata ~ \"\\.(.*?)\\.\") {\n set var.netacea_mitata_cookie_encrypted = re.group.1;\n }\n if (req.http.Cookie:_mitata ~ \"([^\\.]+$)\") {\n set var.netacea_mitata_cookie_sig = re.group.1;\n }\n set var.netacea_mitata_cookie_hex = crypto.decrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_iv, var.netacea_mitata_cookie_encrypted);\n set var.netacea_mitata_cookie_base64 = bin.hex_to_base64(var.netacea_mitata_cookie_hex);\n set var.netacea_mitata_cookie_value = digest.base64_decode(var.netacea_mitata_cookie_base64);\n set req.http.Cookie:_mitata = var.netacea_mitata_cookie_value;\n if(var.netacea_mitata_cookie_sig != digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_cookie_encrypted)) {\n unset req.http.Cookie:_mitata;\n }\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"^(.*?)\\.\") {\n if (req.http.Cookie:_mitatacaptcha ~ \"^(.*?)\\.\") {\n set var.netacea_captcha_iv = re.group.1;\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"\\.(.*?)\\.\") {\n set var.netacea_mitata_captcha_cookie_encrypted = re.group.1;\n }\n if (req.http.Cookie:_mitatacaptcha ~ \"([^\\.]+$)\") {\n set var.netacea_mitata_captcha_cookie_sig = re.group.1;\n }\n set var.netacea_mitata_captcha_cookie_hex = crypto.decrypt_hex(aes256, ctr, nopad, var.netacea_encryption_key, var.netacea_captcha_iv, var.netacea_mitata_captcha_cookie_encrypted);\n set var.netacea_mitata_captcha_cookie_base64 = bin.hex_to_base64(var.netacea_mitata_captcha_cookie_hex);\n set var.netacea_mitata_captcha_cookie_value = digest.base64_decode(var.netacea_mitata_captcha_cookie_base64);\n set req.http.Cookie:_mitatacaptcha = var.netacea_mitata_captcha_cookie_value;\n if(var.netacea_mitata_captcha_cookie_sig != digest.hmac_sha256(var.netacea_mitSvc_secret, var.netacea_mitata_captcha_cookie_encrypted)) {\n unset req.http.Cookie:_mitatacaptcha;\n }\n }\n }\n}\nsub cleanup_netacea_variables {\n if (fastly.ff.visits_this_service > 0) {\n return;\n }\n set req.http.netacea_best_mitigation_code = \"000\";\n set req.http.netacea_match = \"0\";\n set req.http.netacea_mitigate = \"0\";\n set req.http.netacea_captcha = \"0\";\n unset req.http.mit_status;\n unset req.http.netacea_bctype_string;\n unset req.http.netacea_best_mitigation;\n unset req.http.netacea_cookies;\n unset req.http.netacea_mitata_captcha_cookie_expiry;\n unset req.http.netacea_mitata_captcha_cookie_value;\n unset req.http.netacea_mitata_must_reauthenticate;\n unset req.http.netacea_require_revalidation;\n unset req.http.netacea_set_cookies;\n unset req.http.X-Netacea-Match;\n unset req.http.X-Netacea-Mitigate;\n unset req.http.X-Netacea-Captcha;\n unset req.http.X-Netacea-Event-ID;\n unset req.http.X-Netacea-Api-Key;\n unset req.http.X-Netacea-Captcha-Status;\n unset req.http.X-Netacea-UserId;\n unset req.http.X-Netacea-Compile-JSON;\n unset req.http.x-netacea;\n}\nsub netacea_check_req {\n if (req.is_purge) {\n return;\n }\n declare local var.netacea_mitSvc_authenticate BOOL;\n declare local var.netacea_mitSvc_apiKey STRING;\n declare local var.netacea_use_relative_path_captcha_assets STRING;\n declare local var.captcha_path STRING;\n set req.http.x-netacea:integration_mode = get_netacea_integration_mode();\n if (req.http.x-netacea:netacea_check_req_called || fastly.ff.visits_this_service > 0) {\n return;\n }\n if (std.strlen(req.http.x-netacea:integration_mode) == 0) {\n return;\n }\n set req.http.x-netacea:netacea_check_req_called = \"true\";\n unset req.http.netacea_processed;\n if (is_path_ignored()) {\n return;\n }\n if (req.restarts == 0) {\n call set_netacea_ip_header;\n if (req.http.x-netacea:integration_mode != \"BYPASS\") {\n set var.netacea_mitSvc_authenticate = true;\n call normalise_netacea_cookie_names;\n call decrypt_netacea_cookies_values;\n call process_netacea_mitata_cookie;\n }\n } else {\n if (req.http.X-Netacea-Compile-JSON == \"requested\") {\n set req.http.netacea_processed = \"1\";\n set req.http.X-Netacea-Compile-JSON = \"processing\";\n error 601;\n }\n if (req.http.x-netacea:integration_mode == \"MITIGATE\" && req.http.netacea_best_mitigation == \"block\") {\n error 403;\n }\n }\n set var.netacea_mitSvc_apiKey = get_netacea_config_api_key();\n set var.netacea_use_relative_path_captcha_assets = get_netacea_config_use_relative_path_captcha_assets();\n set var.captcha_path = get_netacea_captcha_path();\n if (var.netacea_use_relative_path_captcha_assets == \"true\") {\n if (std.prefixof(req.url.path, \"/Mitigations/\") && req.method == \"GET\") {\n if (std.suffixof(req.url.path, \".css\") || std.suffixof(req.url.path, \".js\")) {\n set req.backend = F_CaptchaAssets;\n return(lookup);\n }\n }\n }\n if (var.captcha_path != \"\" && urldecode(req.url.path) == var.captcha_path) {\n set req.backend = F_MitSvc;\n set req.http.x-netacea:mit_svc_start_time = time.elapsed.msec;\n if (req.backend.healthy) {\n set req.http.netacea_origin_method = \"GET\";\n set req.http.netacea_processed = \"1\";\n set req.http.netacea_captcha_path = \"1\";\n set req.http.netacea_origin_host = req.http.host;\n set req.http.netacea_origin_url = req.url;\n set req.url = \"/captcha?\" + req.url.qs;\n set req.http.X-Netacea-Api-Key = var.netacea_mitSvc_apiKey;\n return(lookup);\n }\n }\n if (req.http.x-netacea:cookie_session_status == \"2\") {\n set var.netacea_mitSvc_authenticate = false;\n }\n set req.http.mitigation_user_id = req.http.X-Netacea-UserId;\n set req.http.integration_type = get_netacea_config_integration_type();\n set req.http.integration_version = get_netacea_config_integration_version();\n if (var.netacea_mitSvc_authenticate) {\n set req.http.netacea_set_cookies = \"1\";\n } else {\n if (req.http.x-netacea:integration_mode == \"INJECT\" && req.restarts == 0) {\n set req.http.X-Netacea-Match = req.http.netacea_match;\n set req.http.X-Netacea-Mitigate = req.http.netacea_mitigate;\n set req.http.X-Netacea-Captcha = req.http.netacea_captcha;\n }\n }\n if (req.http.x-netacea:integration_mode ~ \"(MITIGATE|INJECT)\" && var.netacea_mitSvc_authenticate) {\n set req.backend = F_MitSvc;\n set req.http.x-netacea:mit_svc_start_time = time.elapsed.msec;\n if (req.backend.healthy) {\n unset req.http.netacea_match;\n unset req.http.netacea_mitigate;\n unset req.http.netacea_captcha;\n unset req.http.Cookie:_mitata;\n set req.http.netacea_origin_method = req.method;\n set req.http.netacea_processed = \"1\";\n set req.http.netacea_origin_host = req.http.host;\n set req.http.netacea_origin_url = req.url;\n if (req.url != \"/AtaVerifyCaptcha\") {\n set req.method = \"GET\";\n set req.url = \"/\";\n }\n set req.http.X-Netacea-Api-Key = var.netacea_mitSvc_apiKey;\n return(pass);\n }\n }\n}\n", "type": "init" } ], - "version": "5.10.1" + "version": "5.10.6" }