From 5534777fff91e2a0c643c60868213d2ee65318d6 Mon Sep 17 00:00:00 2001 From: Sirn Thanabulpong Date: Wed, 24 Jan 2024 09:49:36 +0900 Subject: [PATCH] varnishd: add a feature flag to disable bans in VCL Add vcl_ban feature flag to disallow usage of ban() in VCL to prevent a possible DoS scenario in a multi-tenant setup. --- bin/varnishd/cache/cache_vrt.c | 5 ++++ bin/varnishtest/tests/v00075.vtc | 46 ++++++++++++++++++++++++++++++++ include/tbl/feature_bits.h | 5 ++++ include/tbl/params.h | 3 ++- 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 bin/varnishtest/tests/v00075.vtc diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c index 7f4378fb98f..1f785fa4f14 100644 --- a/bin/varnishd/cache/cache_vrt.c +++ b/bin/varnishd/cache/cache_vrt.c @@ -909,6 +909,11 @@ VRT_ban_string(VRT_CTX, VCL_STRING str) CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + if (!FEATURE(FEATURE_VCL_BAN)) { + VRT_fail(ctx, "ban(): Feature flag vcl_ban is off"); + return (vrt_ban_error(ctx, "Feature flag vcl_ban is off"));; + } + if (str == NULL) return (vrt_ban_error(ctx, "Null argument")); diff --git a/bin/varnishtest/tests/v00075.vtc b/bin/varnishtest/tests/v00075.vtc new file mode 100644 index 00000000000..16039b8fede --- /dev/null +++ b/bin/varnishtest/tests/v00075.vtc @@ -0,0 +1,46 @@ +varnishtest "Test vcl_ban" + +server s1 { + rxreq + txresp -status 200 -body "ban" +} -start + +varnish v1 -arg "-p feature=-vcl_ban" -vcl+backend { + sub vcl_recv { + ban("obj.status == 0"); + } +} -start + +logexpect l1 -v v1 { + expect * 1001 VCL_Error "ban\\(\\): Feature flag vcl_ban is off" +} -start + +client c1 { + txreq -url "/ban" + rxresp + expect resp.status == 503 +} -run + +logexpect l1 -wait + +varnish v1 -cliok "param.set feature +vcl_ban" + +client c2 { + txreq -url "/ban" + rxresp + expect resp.status == 200 +} -run + +varnish v1 -cliok "param.set feature -vcl_ban" + +logexpect l2 -v v1 { + expect * * VCL_Error "ban\\(\\): Feature flag vcl_ban is off" +} -start + +client c3 { + txreq -url "/ban" + rxresp + expect resp.status == 503 +} -run + +logexpect l2 -wait diff --git a/include/tbl/feature_bits.h b/include/tbl/feature_bits.h index 808efe9174c..1896c196365 100644 --- a/include/tbl/feature_bits.h +++ b/include/tbl/feature_bits.h @@ -96,6 +96,11 @@ FEATURE_BIT(VCL_REQ_RESET, vcl_req_reset, "When this happens MAIN.req_reset is incremented." ) +FEATURE_BIT(VCL_BAN, vcl_ban, + "Allow the use of bans in VCL. " + "When this is turned off, bans can only be issued through the CLI." +) + #undef FEATURE_BIT /*lint -restore */ diff --git a/include/tbl/params.h b/include/tbl/params.h index 7c093baa95e..a532d3bf387 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -1933,7 +1933,8 @@ PARAM_BITS( /* def */ "none," "+validate_headers," - "+vcl_req_reset", + "+vcl_req_reset," + "+vcl_ban", /* descr */ "Enable/Disable various minor features.\n" "\tdefault\tSet default value (deprecated: use param.reset)\n"