diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | devstack/files/apache-trove-api.template | 2 | ||||
-rw-r--r-- | devstack/plugin.sh | 2 | ||||
-rw-r--r-- | doc/source/install/apache-mod-wsgi.rst | 2 | ||||
-rw-r--r-- | etc/apache2/trove | 2 | ||||
-rw-r--r-- | releasenotes/notes/fix-illegal-value-be1acadc8c54c224.yaml | 6 | ||||
-rw-r--r-- | releasenotes/source/index.rst | 1 | ||||
-rw-r--r-- | releasenotes/source/zed.rst | 6 | ||||
-rw-r--r-- | setup.cfg | 2 | ||||
-rw-r--r-- | tox.ini | 2 | ||||
-rw-r--r-- | trove/backup/service.py | 3 | ||||
-rw-r--r-- | trove/cmd/app_wsgi.py (renamed from trove/cmd/app.wsgi) | 1 | ||||
-rw-r--r-- | trove/common/exception.py | 4 | ||||
-rw-r--r-- | trove/common/utils.py | 11 | ||||
-rw-r--r-- | trove/db/sqlalchemy/session.py | 4 | ||||
-rw-r--r-- | trove/tests/unittests/common/test_utils.py | 16 | ||||
-rw-r--r-- | zuul.d/projects.yaml | 6 |
17 files changed, 67 insertions, 8 deletions
@@ -30,6 +30,11 @@ trove.iml # Files generated by Visual Studio Code .vscode/ +# Files generated by setup.py +*.egg-info +build +.eggs + # Sphinx doc/build/* doc/source/api/* diff --git a/devstack/files/apache-trove-api.template b/devstack/files/apache-trove-api.template index 06c88b26..767f18cf 100644 --- a/devstack/files/apache-trove-api.template +++ b/devstack/files/apache-trove-api.template @@ -21,7 +21,7 @@ Listen %TROVE_SERVICE_PORT% <VirtualHost *:%TROVE_SERVICE_PORT%> WSGIDaemonProcess trove-api user=%USER% processes=%APIWORKERS% threads=1 display-name=%{GROUP} - WSGIScriptAlias / %TROVE_WSGI_DIR%/app.wsgi + WSGIScriptAlias / %TROVE_WSGI_DIR%/app_wsgi.py WSGIApplicationGroup %{GLOBAL} WSGIProcessGroup trove-api WSGIPassAuthorization On diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 2b34158e..cbcc56f6 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -169,7 +169,7 @@ function config_trove_apache_wsgi { local trove_apache_conf sudo mkdir -p ${TROVE_WSGI_DIR} - sudo cp $TROVE_DIR/trove/cmd/app.wsgi $TROVE_WSGI_DIR/app.wsgi + sudo cp $TROVE_DIR/trove/cmd/app_wsgi.py $TROVE_WSGI_DIR/app_wsgi.py trove_apache_conf=$(apache_site_config_for trove-api) sudo cp $TROVE_DEVSTACK_FILES/apache-trove-api.template ${trove_apache_conf} sudo sed -e " diff --git a/doc/source/install/apache-mod-wsgi.rst b/doc/source/install/apache-mod-wsgi.rst index 61968662..7b4d855d 100644 --- a/doc/source/install/apache-mod-wsgi.rst +++ b/doc/source/install/apache-mod-wsgi.rst @@ -36,7 +36,7 @@ Installing API behind mod_wsgi * Modify the ``WSGIDaemonProcess`` directive to set the ``user`` and ``group`` values to appropriate user on your server. * Modify the ``WSGIScriptAlias`` directive to point to the - trove/api/app.wsgi script. + trove/api/app_wsgi.py script. * Modify the ``Directory`` directive to set the path to the Trove API code. * Modify the ``ErrorLog and CustomLog`` to redirect the logs to the right diff --git a/etc/apache2/trove b/etc/apache2/trove index 1ed82c26..d8257423 100644 --- a/etc/apache2/trove +++ b/etc/apache2/trove @@ -19,7 +19,7 @@ Listen 8779 <VirtualHost *:8779> WSGIDaemonProcess trove-api user=stack group=stack processes=2 threads=2 display-name=%{GROUP} - WSGIScriptAlias / /opt/stack/trove/trove/cmd/app.wsgi + WSGIScriptAlias / /opt/stack/trove/trove/cmd/app_wsgi.py WSGIProcessGroup trove-api ErrorLog /var/log/httpd/trove_error.log diff --git a/releasenotes/notes/fix-illegal-value-be1acadc8c54c224.yaml b/releasenotes/notes/fix-illegal-value-be1acadc8c54c224.yaml new file mode 100644 index 00000000..9ea3aa41 --- /dev/null +++ b/releasenotes/notes/fix-illegal-value-be1acadc8c54c224.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + check if the user input is legal, currently, trove may have a + RCE vulnerability. more details see: + `Stroy 2010004 <https://storyboard.openstack.org/#!/story/2010004>`__ diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst index 17e4cf44..7dbe6f45 100644 --- a/releasenotes/source/index.rst +++ b/releasenotes/source/index.rst @@ -6,6 +6,7 @@ :maxdepth: 1 unreleased + zed yoga xena wallaby diff --git a/releasenotes/source/zed.rst b/releasenotes/source/zed.rst new file mode 100644 index 00000000..9608c05e --- /dev/null +++ b/releasenotes/source/zed.rst @@ -0,0 +1,6 @@ +======================== +Zed Series Release Notes +======================== + +.. release-notes:: + :branch: stable/zed @@ -26,6 +26,8 @@ packages = trove [entry_points] +wsgi_scripts = + trove-wsgi = trove.cmd.app_wsgi:wsgimain console_scripts = trove-api = trove.cmd.api:main trove-taskmanager = trove.cmd.taskmanager:main @@ -65,7 +65,7 @@ builtins = _ # add *.yaml for playbooks/trove-devstack-base.yaml, as it will be matched by # trove-* in the "filename" configuration. exclude=.venv,.tox,.git,dist,doc,*egg,tools,etc,build,*.po,*.pot,integration,releasenotes,*.yaml -filename=*.py,trove-*,app.wsgi +filename=*.py,trove-* [hacking] import_exceptions = trove.common.i18n diff --git a/trove/backup/service.py b/trove/backup/service.py index 8b3d9d0f..7e3d3fe9 100644 --- a/trove/backup/service.py +++ b/trove/backup/service.py @@ -88,6 +88,9 @@ class BackupController(wsgi.Controller): swift_container = data.get('swift_container') restore_from = data.get('restore_from') + if swift_container: + utils.validate_command(swift_container) + context.notification = notification.DBaaSBackupCreate( context, request=req) diff --git a/trove/cmd/app.wsgi b/trove/cmd/app_wsgi.py index a134539c..78eadd5b 100644 --- a/trove/cmd/app.wsgi +++ b/trove/cmd/app_wsgi.py @@ -38,4 +38,5 @@ def wsgimain(CONF): LOG.debug("Trove started on %s", CONF.host) return pastedeploy.paste_deploy_app(conf_file, 'trove', {}) + application = wsgimain() diff --git a/trove/common/exception.py b/trove/common/exception.py index d4b44b0c..cdc6755f 100644 --- a/trove/common/exception.py +++ b/trove/common/exception.py @@ -61,6 +61,10 @@ class InvalidRPCConnectionReuse(TroveError): message = _("Invalid RPC Connection Reuse.") +class InvalidValue(TroveError): + message = _("The value is not allowed: %(value)s.") + + class NotFound(TroveError): message = _("Resource %(uuid)s cannot be found.") diff --git a/trove/common/utils.py b/trove/common/utils.py index bbddef87..e11a66c7 100644 --- a/trove/common/utils.py +++ b/trove/common/utils.py @@ -17,6 +17,7 @@ from collections import abc import inspect import os +import shlex import shutil import uuid import urllib.parse as urlparse @@ -423,3 +424,13 @@ def req_to_text(req): parts.extend([b'', safe_encode(req.body)]) return b'\r\n'.join(parts).decode(req.charset) + + +def validate_command(string): + """ + Check if the string is legal for command + + raise invalidvalue if illegal + """ + if string != shlex.quote(string): + raise exception.InvalidValue(value=string) diff --git a/trove/db/sqlalchemy/session.py b/trove/db/sqlalchemy/session.py index 39a0f218..1d2a1e08 100644 --- a/trove/db/sqlalchemy/session.py +++ b/trove/db/sqlalchemy/session.py @@ -94,6 +94,10 @@ def _create_facade(options): # use enginefacade.from_config() instead database_opts = dict(CONF.database) database_opts.pop('query_log') + # FIXME(wuchunyang): we need to remove reliance on autocommit + # semantics ASAP. since it's not compatible with + # SQLAlchemy 2.0 + database_opts['autocommit'] = True _FACADE = session.EngineFacade( options['database']['connection'], **database_opts diff --git a/trove/tests/unittests/common/test_utils.py b/trove/tests/unittests/common/test_utils.py index 4f31d08b..e8a3600e 100644 --- a/trove/tests/unittests/common/test_utils.py +++ b/trove/tests/unittests/common/test_utils.py @@ -186,3 +186,19 @@ class TestUtils(trove_testtools.TestCase): expected = ('GET / HTTP/1.0\r\nHost: localhost:80\r\n' 'X-Auth-Project-Id: \u6d4b\u8bd5') self.assertEqual(expected, utils.req_to_text(req)) + + def test_validate_command(self): + string1 = "hello_world" + string2 = "hello world" + string3 = "hello@world_123" + string4 = "example.com/databse/mysql:5.7" + string5 = 'test --db-user="$(touch /rce_successful.txt)"' + self.assertIsNone(utils.validate_command(string1)) + self.assertRaises(exception.InvalidValue, + utils.validate_command, + string2) + self.assertIsNone(utils.validate_command(string3)) + self.assertIsNone(utils.validate_command(string4)) + self.assertRaises(exception.InvalidValue, + utils.validate_command, + string5) diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index 32e5aa1e..aacdd614 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -1,5 +1,6 @@ - +--- - project: + queue: trove templates: - check-requirements - openstack-cover-jobs @@ -27,7 +28,6 @@ - trove-functional-mysql: voting: false gate: - queue: trove jobs: - trove-tempest: voting: false @@ -41,4 +41,4 @@ periodic: jobs: - publish-trove-guest-image-ubuntu-focal - - publish-trove-guest-image-ubuntu-focal-dev
\ No newline at end of file + - publish-trove-guest-image-ubuntu-focal-dev |