[1.10.x] Fixed CVE-2016-9013 -- Generated a random database user password when running tests on Oracle.

This is a security fix.
This commit is contained in:
Marti Raudsepp 2016-10-24 15:22:00 -04:00 committed by Tim Graham
parent 3f8fcfbf3c
commit 34e10720d8
5 changed files with 60 additions and 5 deletions

View File

@ -4,11 +4,11 @@ import time
from django.conf import settings from django.conf import settings
from django.db.backends.base.creation import BaseDatabaseCreation from django.db.backends.base.creation import BaseDatabaseCreation
from django.db.utils import DatabaseError from django.db.utils import DatabaseError
from django.utils.crypto import get_random_string
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.six.moves import input from django.utils.six.moves import input
TEST_DATABASE_PREFIX = 'test_' TEST_DATABASE_PREFIX = 'test_'
PASSWORD = 'Im_a_lumberjack'
class DatabaseCreation(BaseDatabaseCreation): class DatabaseCreation(BaseDatabaseCreation):
@ -223,7 +223,11 @@ class DatabaseCreation(BaseDatabaseCreation):
] ]
# Ignore "user already exists" error when keepdb is on # Ignore "user already exists" error when keepdb is on
acceptable_ora_err = 'ORA-01920' if keepdb else None acceptable_ora_err = 'ORA-01920' if keepdb else None
self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err) success = self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err)
# If the password was randomly generated, change the user accordingly.
if not success and self._test_settings_get('PASSWORD') is None:
set_password = "ALTER USER %(user)s IDENTIFIED BY %(password)s"
self._execute_statements(cursor, [set_password], parameters, verbosity)
# Most test-suites can be run without the create-view privilege. But some need it. # Most test-suites can be run without the create-view privilege. But some need it.
extra = "GRANT CREATE VIEW TO %(user)s" extra = "GRANT CREATE VIEW TO %(user)s"
success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031') success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031')
@ -298,7 +302,7 @@ class DatabaseCreation(BaseDatabaseCreation):
""" """
settings_dict = self.connection.settings_dict settings_dict = self.connection.settings_dict
val = settings_dict['TEST'].get(key, default) val = settings_dict['TEST'].get(key, default)
if val is None: if val is None and prefixed:
val = TEST_DATABASE_PREFIX + settings_dict[prefixed] val = TEST_DATABASE_PREFIX + settings_dict[prefixed]
return val return val
@ -315,7 +319,11 @@ class DatabaseCreation(BaseDatabaseCreation):
return self._test_settings_get('USER', prefixed='USER') return self._test_settings_get('USER', prefixed='USER')
def _test_database_passwd(self): def _test_database_passwd(self):
return self._test_settings_get('PASSWORD', default=PASSWORD) password = self._test_settings_get('PASSWORD')
if password is None and self._test_user_create():
# Oracle passwords are limited to 30 chars and can't contain symbols.
password = get_random_string(length=30)
return password
def _test_database_tblspace(self): def _test_database_tblspace(self):
return self._test_settings_get('TBLSPACE', prefixed='USER') return self._test_settings_get('TBLSPACE', prefixed='USER')

View File

@ -797,7 +797,12 @@ Default: ``None``
This is an Oracle-specific setting. This is an Oracle-specific setting.
The password to use when connecting to the Oracle database that will be used The password to use when connecting to the Oracle database that will be used
when running tests. If not provided, Django will use a hardcoded default value. when running tests. If not provided, Django will generate a random password.
.. versionchanged:: 1.10.3
Older versions used a hardcoded default password. This was also changed
in 1.9.11 and 1.8.16 to fix possible security implications.
.. setting:: TEST_TBLSPACE .. setting:: TEST_TBLSPACE

View File

@ -6,6 +6,20 @@ Django 1.10.3 release notes
Django 1.10.3 fixes two security issues and several bugs in 1.10.2. Django 1.10.3 fixes two security issues and several bugs in 1.10.2.
User with hardcoded password created when running tests on Oracle
=================================================================
When running tests with an Oracle database, Django creates a temporary database
user. In older versions, if a password isn't manually specified in the database
settings ``TEST`` dictionary, a hardcoded password is used. This could allow
an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using
the ``manage.py test --keepdb`` option or if the user has an active session
(such as an attacker's connection).
A randomly generated password is now used for each test run.
Bugfixes Bugfixes
======== ========

View File

@ -5,3 +5,17 @@ Django 1.8.16 release notes
*November 1, 2016* *November 1, 2016*
Django 1.8.16 fixes two security issues in 1.8.15. Django 1.8.16 fixes two security issues in 1.8.15.
User with hardcoded password created when running tests on Oracle
=================================================================
When running tests with an Oracle database, Django creates a temporary database
user. In older versions, if a password isn't manually specified in the database
settings ``TEST`` dictionary, a hardcoded password is used. This could allow
an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using
the ``manage.py test --keepdb`` option or if the user has an active session
(such as an attacker's connection).
A randomly generated password is now used for each test run.

View File

@ -5,3 +5,17 @@ Django 1.9.11 release notes
*November 1, 2016* *November 1, 2016*
Django 1.9.11 fixes two security issues in 1.9.10. Django 1.9.11 fixes two security issues in 1.9.10.
User with hardcoded password created when running tests on Oracle
=================================================================
When running tests with an Oracle database, Django creates a temporary database
user. In older versions, if a password isn't manually specified in the database
settings ``TEST`` dictionary, a hardcoded password is used. This could allow
an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using
the ``manage.py test --keepdb`` option or if the user has an active session
(such as an attacker's connection).
A randomly generated password is now used for each test run.