From 2a1d226684da9996d2019c7690d0b5b6fd1fe044 Mon Sep 17 00:00:00 2001 From: Sida Chen Date: Wed, 13 Mar 2019 12:30:51 -0400 Subject: [PATCH] Validate service key name on server side All requests to post or update service key name are enforced to match: ^[\s a-zA-Z0-9\-_:/]*$ --- endpoints/api/superuser.py | 16 ++++++++++++---- util/validation.py | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/endpoints/api/superuser.py b/endpoints/api/superuser.py index 72cb1c4f9..f8c6711e7 100644 --- a/endpoints/api/superuser.py +++ b/endpoints/api/superuser.py @@ -28,6 +28,7 @@ from endpoints.api.superuser_models_pre_oci import (pre_oci_model, ServiceKeyDoe InvalidRepositoryBuildException) from endpoints.api.logs import _validate_logs_arguments from util.useremails import send_confirmation_email, send_recovery_email +from util.validation import validate_service_key_name from _init import ROOT_DIR logger = logging.getLogger(__name__) @@ -611,6 +612,9 @@ class SuperUserServiceKeyManagement(ApiResource): def post(self): if SuperUserPermission().can(): body = request.get_json() + key_name = body.get('name', '') + if not validate_service_key_name(key_name): + raise InvalidRequest('Invalid service key friendly name: %s' % key_name) # Ensure we have a valid expiration date if specified. expiration_date = body.get('expiration', None) @@ -635,7 +639,7 @@ class SuperUserServiceKeyManagement(ApiResource): # Generate a key with a private key that we *never save*. (private_key, key_id) = pre_oci_model.generate_service_key(body['service'], expiration_date, metadata=metadata, - name=body.get('name', '')) + name=key_name) # Auto-approve the service key. pre_oci_model.approve_service_key(key_id, user, ServiceKeyApprovalType.SUPERUSER, notes=body.get('notes', '')) @@ -645,7 +649,7 @@ class SuperUserServiceKeyManagement(ApiResource): 'kid': key_id, 'preshared': True, 'service': body['service'], - 'name': body.get('name', ''), + 'name': key_name, 'expiration_date': expiration_date, 'auto_approved': True, } @@ -655,7 +659,7 @@ class SuperUserServiceKeyManagement(ApiResource): return jsonify({ 'kid': key_id, - 'name': body.get('name', ''), + 'name': key_name, 'service': body['service'], 'public_key': private_key.publickey().exportKey('PEM'), 'private_key': private_key.exportKey('PEM'), @@ -744,7 +748,11 @@ class SuperUserServiceKey(ApiResource): pre_oci_model.set_key_expiration(kid, expiration_date) if 'name' in body or 'metadata' in body: - pre_oci_model.update_service_key(kid, body.get('name'), body.get('metadata')) + key_name = body.get('name') + if not validate_service_key_name(key_name): + raise InvalidRequest('Invalid service key friendly name: %s' % key_name) + + pre_oci_model.update_service_key(kid, key_name, body.get('metadata')) log_action('service_key_modify', None, key_log_metadata) updated_key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False) diff --git a/util/validation.py b/util/validation.py index eabe290c5..8da4a456e 100644 --- a/util/validation.py +++ b/util/validation.py @@ -15,6 +15,7 @@ MAX_USERNAME_LENGTH = 255 VALID_LABEL_KEY_REGEX = r'^[a-z0-9](([a-z0-9]|[-.](?![.-]))*[a-z0-9])?$' VALID_USERNAME_REGEX = r'^([a-z0-9]+(?:[._-][a-z0-9]+)*)$' +VALID_SERVICE_KEY_NAME_REGEX = r'^[\s a-zA-Z0-9\-_:/]*$' INVALID_USERNAME_CHARACTERS = r'[^a-z0-9_]' @@ -99,3 +100,7 @@ def validate_postgres_precondition(driver): "pg_trgm" extension does not exists in the database. Please run `CREATE EXTENSION IF NOT EXISTS pg_trgm;` as superuser on this database. """) + + +def validate_service_key_name(name): + return name is None or bool(re.match(VALID_SERVICE_KEY_NAME_REGEX, name))