CVE-2016-9013
Description
Django 1.8.x before 1.8.16, 1.9.x before 1.9.11, and 1.10.x before 1.10.3 use a hardcoded password for a temporary database user created when running tests with an Oracle database, which makes it easier for remote attackers to obtain access to the database server by leveraging failure to manually specify a password in the database settings TEST dictionary.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
DjangoPyPI | >= 1.10a1, < 1.10.3 | 1.10.3 |
DjangoPyPI | >= 1.9a1, < 1.9.11 | 1.9.11 |
DjangoPyPI | >= 1.8a1, < 1.8.16 | 1.8.16 |
Affected products
36cpe:2.3:a:djangoproject:django:1.10:*:*:*:*:*:*:*+ 29 more
- cpe:2.3:a:djangoproject:django:1.10:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.10.1:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.10.2:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.1:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.10:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.11:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.12:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.13:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.14:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.15:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.2:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.3:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.4:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.5:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.6:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.7:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.8:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.8.9:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.1:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.10:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.2:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.3:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.4:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.5:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.6:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.7:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.8:*:*:*:*:*:*:*
- cpe:2.3:a:djangoproject:django:1.9.9:*:*:*:*:*:*:*
cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:lts:*:*:*+ 3 more
- cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:lts:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:14.04:*:*:*:lts:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:16.10:*:*:*:*:*:*:*
cpe:2.3:o:fedoraproject:fedora:24:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:fedoraproject:fedora:24:*:*:*:*:*:*:*
- cpe:2.3:o:fedoraproject:fedora:25:*:*:*:*:*:*:*
Patches
370f99952965a[1.8.x] Fixed CVE-2016-9013 -- Generated a random database user password when running tests on Oracle.
3 files changed · +31 −5
django/db/backends/oracle/creation.py+12 −4 modified@@ -4,10 +4,10 @@ from django.conf import settings from django.db.backends.base.creation import BaseDatabaseCreation from django.db.utils import DatabaseError +from django.utils.crypto import get_random_string from django.utils.six.moves import input TEST_DATABASE_PREFIX = 'test_' -PASSWORD = 'Im_a_lumberjack' class DatabaseCreation(BaseDatabaseCreation): @@ -188,7 +188,11 @@ def _create_test_user(self, cursor, parameters, verbosity, keepdb=False): ] # Ignore "user already exists" error when keepdb is on 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. extra = "GRANT CREATE VIEW TO %(user)s" success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031') @@ -263,7 +267,7 @@ def _test_settings_get(self, key, default=None, prefixed=None): """ settings_dict = self.connection.settings_dict val = settings_dict['TEST'].get(key, default) - if val is None: + if val is None and prefixed: val = TEST_DATABASE_PREFIX + settings_dict[prefixed] return val @@ -280,7 +284,11 @@ def _test_database_user(self): return self._test_settings_get('USER', prefixed='USER') 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): return self._test_settings_get('TBLSPACE', prefixed='USER')
docs/ref/settings.txt+5 −1 modified@@ -773,7 +773,11 @@ Default: ``None`` This is an Oracle-specific setting. 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.8.16 + + Older versions used a hardcoded default password. .. setting:: TEST_TBLSPACE
docs/releases/1.8.16.txt+14 −0 modified@@ -5,3 +5,17 @@ Django 1.8.16 release notes *November 1, 2016* 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.
4844d86c7728[1.9.x] Fixed CVE-2016-9013 -- Generated a random database user password when running tests on Oracle.
4 files changed · +46 −5
django/db/backends/oracle/creation.py+12 −4 modified@@ -4,11 +4,11 @@ from django.conf import settings from django.db.backends.base.creation import BaseDatabaseCreation from django.db.utils import DatabaseError +from django.utils.crypto import get_random_string from django.utils.functional import cached_property from django.utils.six.moves import input TEST_DATABASE_PREFIX = 'test_' -PASSWORD = 'Im_a_lumberjack' class DatabaseCreation(BaseDatabaseCreation): @@ -223,7 +223,11 @@ def _create_test_user(self, cursor, parameters, verbosity, keepdb=False): ] # Ignore "user already exists" error when keepdb is on 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. extra = "GRANT CREATE VIEW TO %(user)s" success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031') @@ -298,7 +302,7 @@ def _test_settings_get(self, key, default=None, prefixed=None): """ settings_dict = self.connection.settings_dict val = settings_dict['TEST'].get(key, default) - if val is None: + if val is None and prefixed: val = TEST_DATABASE_PREFIX + settings_dict[prefixed] return val @@ -315,7 +319,11 @@ def _test_database_user(self): return self._test_settings_get('USER', prefixed='USER') 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): return self._test_settings_get('TBLSPACE', prefixed='USER')
docs/ref/settings.txt+6 −1 modified@@ -814,7 +814,12 @@ Default: ``None`` This is an Oracle-specific setting. 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.9.11 + + Older versions used a hardcoded default password. This was also changed + in 1.8.16 to fix possible security implications. .. setting:: TEST_TBLSPACE
docs/releases/1.8.16.txt+14 −0 modified@@ -5,3 +5,17 @@ Django 1.8.16 release notes *November 1, 2016* 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.
docs/releases/1.9.11.txt+14 −0 modified@@ -5,3 +5,17 @@ Django 1.9.11 release notes *November 1, 2016* 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.
34e10720d81b[1.10.x] Fixed CVE-2016-9013 -- Generated a random database user password when running tests on Oracle.
5 files changed · +60 −5
django/db/backends/oracle/creation.py+12 −4 modified@@ -4,11 +4,11 @@ from django.conf import settings from django.db.backends.base.creation import BaseDatabaseCreation from django.db.utils import DatabaseError +from django.utils.crypto import get_random_string from django.utils.functional import cached_property from django.utils.six.moves import input TEST_DATABASE_PREFIX = 'test_' -PASSWORD = 'Im_a_lumberjack' class DatabaseCreation(BaseDatabaseCreation): @@ -223,7 +223,11 @@ def _create_test_user(self, cursor, parameters, verbosity, keepdb=False): ] # Ignore "user already exists" error when keepdb is on 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. extra = "GRANT CREATE VIEW TO %(user)s" success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031') @@ -298,7 +302,7 @@ def _test_settings_get(self, key, default=None, prefixed=None): """ settings_dict = self.connection.settings_dict val = settings_dict['TEST'].get(key, default) - if val is None: + if val is None and prefixed: val = TEST_DATABASE_PREFIX + settings_dict[prefixed] return val @@ -315,7 +319,11 @@ def _test_database_user(self): return self._test_settings_get('USER', prefixed='USER') 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): return self._test_settings_get('TBLSPACE', prefixed='USER')
docs/ref/settings.txt+6 −1 modified@@ -797,7 +797,12 @@ Default: ``None`` This is an Oracle-specific setting. 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
docs/releases/1.10.3.txt+14 −0 modified@@ -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. +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 ========
docs/releases/1.8.16.txt+14 −0 modified@@ -5,3 +5,17 @@ Django 1.8.16 release notes *November 1, 2016* 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.
docs/releases/1.9.11.txt+14 −0 modified@@ -5,3 +5,17 @@ Django 1.9.11 release notes *November 1, 2016* 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.
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
16- www.securityfocus.com/bid/94069nvdThird Party AdvisoryVDB Entry
- www.securitytracker.com/id/1037159nvdThird Party AdvisoryVDB Entry
- www.ubuntu.com/usn/USN-3115-1nvdThird Party AdvisoryWEB
- github.com/advisories/GHSA-mv8g-fhh6-6267ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-9013ghsaADVISORY
- www.djangoproject.com/weblog/2016/nov/01/security-releases/nvdRelease NotesVendor Advisory
- www.debian.org/security/2017/dsa-3835nvdWEB
- github.com/django/django/commit/34e10720d81b8d407aa14d763b6a7fe8f13b4f2eghsaWEB
- github.com/django/django/commit/4844d86c7728c1a5a3bbce4ad336a8d32304072bghsaWEB
- github.com/django/django/commit/70f99952965a430daf69eeb9947079aae535d2d0ghsaWEB
- github.com/pypa/advisory-database/tree/main/vulns/django/PYSEC-2016-17.yamlghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/OG5ROMUPS6C7BXELD3TAUUH7OBYV56WQghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QXDKJYHN74BWY3P7AR2UZDVJREQMRE6SghsaWEB
- www.djangoproject.com/weblog/2016/nov/01/security-releasesghsaWEB
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/OG5ROMUPS6C7BXELD3TAUUH7OBYV56WQ/nvd
- lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QXDKJYHN74BWY3P7AR2UZDVJREQMRE6S/nvd
News mentions
0No linked articles in our index yet.