Skip to content

Commit

Permalink
fix: LEAP-38: Rework secret key generation to use data volume more re…
Browse files Browse the repository at this point in the history
…liably (#4716)

fix: LEAP-38: rework secret key generation to use data volume more reliably (#4713)

* fix: LEAP-38: rework secret key generation to use data volume more reliably

* remove key name param

* Update label_studio/core/utils/secret_key.py

---------

Co-authored-by: Jo Booth <jo.m.booth@gmail.com>
  • Loading branch information
bmartel and jombooth committed Aug 29, 2023
1 parent 40c725a commit 46b3fde
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 30 deletions.
9 changes: 5 additions & 4 deletions label_studio/core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@
if not logging.getLogger().hasHandlers():
logging.basicConfig(level=logging.DEBUG, format='%(message)s')

from label_studio.core.utils.io import get_data_dir, generate_key_if_missing
from label_studio.core.utils.io import get_data_dir
from label_studio.core.utils.params import get_bool_env, get_env, get_env_list_int
from label_studio.core.utils.secret_key import generate_secret_key_if_missing

logger = logging.getLogger(__name__)
SILENCED_SYSTEM_CHECKS = []
Expand Down Expand Up @@ -104,9 +105,6 @@

INTERNAL_PORT = '8080'

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = generate_key_if_missing('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = get_bool_env('DEBUG', True)
DEBUG_MODAL_EXCEPTIONS = get_bool_env('DEBUG_MODAL_EXCEPTIONS', True)
Expand All @@ -119,6 +117,9 @@
os.makedirs(BASE_DATA_DIR, exist_ok=True)
logger.info('=> Database and media directory: %s', BASE_DATA_DIR)

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = generate_secret_key_if_missing(BASE_DATA_DIR)

# Databases
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DJANGO_DB_MYSQL = 'mysql'
Expand Down
20 changes: 0 additions & 20 deletions label_studio/core/utils/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
from contextlib import contextmanager
from tempfile import mkstemp, mkdtemp

from django.conf import settings
from django.core.management.utils import get_random_secret_key
from label_studio.core.utils.params import env, env_file
from appdirs import user_config_dir, user_data_dir, user_cache_dir

# full path import results in unit test failures
Expand Down Expand Up @@ -210,20 +207,3 @@ def validate_upload_url(url, block_local_urls=True):
for subnet in local_subnets:
if ipaddress.ip_address(ip) in ipaddress.ip_network(subnet):
raise InvalidUploadUrlError

def generate_key_if_missing(key):
value = env.str(key, "")

if value == "":
print(f'Warning: {key} not found in environment variables will generate a random key.')
value = get_random_secret_key()
try:
with open(env_file, 'a') as f:
f.write(f'\n{key}={value}\n')
except Exception as e:
print(f'Warning: failed to write {key} to .env file: {e}, new key will be regenerated on every server restart. If this key is used for signing, it will invalidate all existing sessions or tokens. Please set {key} in your environment variables to avoid this warning.')

os.environ[key] = value

return value

6 changes: 0 additions & 6 deletions label_studio/core/utils/params.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import os
import environ

from rest_framework.exceptions import ValidationError


env = environ.Env()
data_dir = os.environ.get('LABEL_STUDIO_DATA_DIR', os.path.join(os.path.dirname(__file__), '..', '..', '..', 'data'))
env_file = os.path.join(data_dir, '.env')
environ.Env.read_env(env_file)

def cast_bool_from_str(value):
if isinstance(value, str):
if value.lower() in ['true', 'yes', 'on', '1']:
Expand Down
28 changes: 28 additions & 0 deletions label_studio/core/utils/secret_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import logging
import os
import environ
from django.core.management.utils import get_random_secret_key


logger = logging.getLogger(__name__)


def generate_secret_key_if_missing(data_dir: str) -> str:
env_key = 'SECRET_KEY'
env = environ.Env()
env_filepath = os.path.join(data_dir, '.env')
environ.Env.read_env(env_filepath)

if existing_secret := env.str(env_key, ""):
return existing_secret

logger.warning(f'Warning: {env_key} not found in environment variables. Will generate a random key.')
new_secret = get_random_secret_key()
try:
with open(env_filepath, 'a') as f:
f.write(f'\n{env_key}={new_secret}\n') # nosec
except Exception as e:
logger.warning(f'Warning: failed to write {env_key} to .env file: {e}, new key will be regenerated on every server restart. If this key is used for signing, it will invalidate all existing sessions or tokens. Please set {key} in your environment variables to avoid this warning.')

os.environ[env_key] = new_secret
return new_secret

0 comments on commit 46b3fde

Please sign in to comment.