From 2a1d226684da9996d2019c7690d0b5b6fd1fe044 Mon Sep 17 00:00:00 2001 From: Sida Chen Date: Wed, 13 Mar 2019 12:30:51 -0400 Subject: [PATCH 1/2] 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)) From 97f06e362804aeeccf81514ddf3614b8bff9892e Mon Sep 17 00:00:00 2001 From: Sida Chen Date: Wed, 13 Mar 2019 14:35:57 -0400 Subject: [PATCH 2/2] Frontend service key name regex check - Name is checked in the create preshared key form - Edit friendly name keep prompting until user enters a key that passes regex --- static/directives/service-keys-manager.html | 4 ++-- static/js/directives/ui/service-keys-manager.js | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/static/directives/service-keys-manager.html b/static/directives/service-keys-manager.html index b1267daeb..c87e27660 100644 --- a/static/directives/service-keys-manager.html +++ b/static/directives/service-keys-manager.html @@ -316,9 +316,9 @@ - + - A friendly name for the key for later reference. + A friendly name for the key for later reference. Must match ^[\s a-zA-Z0-9\-_:/]*$. diff --git a/static/js/directives/ui/service-keys-manager.js b/static/js/directives/ui/service-keys-manager.js index 295aa2692..96f9c3959 100644 --- a/static/js/directives/ui/service-keys-manager.js +++ b/static/js/directives/ui/service-keys-manager.js @@ -102,6 +102,17 @@ angular.module('quay').directive('serviceKeysManager', function () { 'value': key.name || '', 'callback': function(value) { if (value != null) { + if (!value.match(/^[\s a-zA-Z0-9\-_:/]*$/)){ + bootbox.alert({ + 'message': 'Invalid friendly name: input does not match ^[\\s a-zA-Z0-9\-_:/]*$', + 'callback': function(){ + $scope.showChangeName(key) + } + }); + + return + } + var data = { 'name': value };