From faa937020aa39ea1a9e90e0d43d54aef56e23cdc Mon Sep 17 00:00:00 2001 From: Smyler Date: Mon, 3 Apr 2023 08:01:17 +0200 Subject: [PATCH] Prevent race conditions on /healthcheck (#2273) In a high availability deployment scenario, two clients may make a request on /healthcheck at the exact same time, which can lead to check_config returning False if the second requests changes the 'healthcheck' cache key before the first one has had time to fetch the value it had set. A solution to counter this is to ensure different keys are used for each healthcheck. --- CTFd/utils/health/__init__.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CTFd/utils/health/__init__.py b/CTFd/utils/health/__init__.py index f49ae6c2..bf5882d7 100644 --- a/CTFd/utils/health/__init__.py +++ b/CTFd/utils/health/__init__.py @@ -1,4 +1,4 @@ -from time import monotonic_ns +from time import time from flask import current_app from sqlalchemy_utils import database_exists @@ -13,6 +13,7 @@ def check_database(): @timed_lru_cache(timeout=30) def check_config(): - value = monotonic_ns() - cache.set("healthcheck", value) - return cache.get("healthcheck") == value + key = "healthcheck" + value = round(time() / 5) * 5 + cache.set(key, value) + return cache.get(key) == value