Skip to content

Scheduled biweekly dependency update for week 31 - #1035

Open
pyup-bot wants to merge 20 commits into
masterfrom
pyup-scheduled-update-2026-08-03
Open

Scheduled biweekly dependency update for week 31#1035
pyup-bot wants to merge 20 commits into
masterfrom
pyup-scheduled-update-2026-08-03

Conversation

@pyup-bot

@pyup-bot pyup-bot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Update cryptography from 44.0.0 to 50.0.0.

Changelog

50.0.0

~~~~~~~~~~~~~~~~~~~

* **SECURITY ISSUE**:
:func:`~cryptography.hazmat.primitives.serialization.pkcs7.pkcs7_decrypt_der`
and its PEM and S/MIME variants no longer expose distinguishable errors or
timing when unwrapping a ``RecipientInfo``'s ``encryptedKey``, which could
act as a Bleichenbacher oracle for callers that decrypt untrusted messages.
A random key is now substituted on failure, as described in :rfc:`3218`.
Credit to **X1AOxiang** for reporting the issue
* Deprecated Diffie-Hellman key exchange over finite fields (FFDH).
Everything FFDH is deprecated, including the types in
``cryptography.hazmat.primitives.asymmetric.dh`` and loading FFDH keys or
parameters with the key loading APIs. Users should migrate to a more
modern key exchange algorithm.
* Added ``xof()`` class methods to
:class:`~cryptography.hazmat.primitives.hashes.SHAKE128` and
:class:`~cryptography.hazmat.primitives.hashes.SHAKE256` for constructing
algorithm instances configured for use with
:class:`~cryptography.hazmat.primitives.hashes.XOFHash`.
* The :mod:`X.509 verification <cryptography.x509.verification>` APIs are now
considered stable and are subject to our API stability policy.
* Added the :doc:`/cobblestone` recipe, an implementation of the
Cobblestone-128 and Cobblestone-256 instantiations of the `C2SP
chunked-encryption specification
<https://c2sp.org/chunked-encryption>`_ for streaming authenticated
encryption of large messages.
* Parsing a Signed Certificate Timestamp list now rejects encodings that
carry trailing bytes after the list or after an individual SCT, instead of
silently ignoring them.
* Added support for using :class:`~cryptography.x509.Name` as a field type in
the :doc:`/hazmat/asn1/index` module.
* Loading a public key or an EC private key now rejects DER where the
``subjectPublicKey`` (or EC ``publicKey``) ``BIT STRING`` declares a non-zero
number of unused bits, instead of silently ignoring it.
* Parsing a CRL entry's ``InvalidityDate`` extension now rejects a
``GeneralizedTime`` that carries fractional seconds or another non-DER form,
matching the strict encoding already required for every other X.509 time
field.
* :func:`~cryptography.x509.ocsp.load_der_ocsp_request` and
:func:`~cryptography.x509.ocsp.load_der_ocsp_response` now reject a request
or response whose ``version`` field is not ``v1``, the only version defined
by RFC 6960, matching the version validation already performed when loading
certificates, CSRs and CRLs.
* :class:`~cryptography.hazmat.primitives.hashes.XOFHash` is now supported
when building against AWS-LC.
* HMAC (and therefore PBKDF2-HMAC) with SHA-3 hashes is now supported when
building against AWS-LC.
* Diffie-Hellman (:doc:`/hazmat/primitives/asymmetric/dh`) is now supported
when building against AWS-LC.
* :func:`~cryptography.hazmat.primitives.serialization.load_der_public_key` and
:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key` now
reject Diffie-Hellman public keys whose modulus is smaller than 512 bits,
matching the minimum already enforced when loading DH private keys and when
constructing :class:`~cryptography.hazmat.primitives.asymmetric.dh.DHParameterNumbers`.
* Added
:class:`~cryptography.hazmat.primitives.asymmetric.mldsa.MLDSAMuHasher` for
incrementally computing the ML-DSA ``mu`` (message representative) used by
the external-mu signing and verification APIs.
* The builtin :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
classes and the classes in
:mod:`~cryptography.hazmat.primitives.asymmetric.padding` can now be
compared with ``==``.
* :class:`~cryptography.x509.CertificateBuilder` now supports creating unsigned
certificates (:rfc:`9925`) with the ``create_unsigned`` method.
* The :mod:`X.509 verification <cryptography.x509.verification>` APIs now
permit ML-DSA-44, ML-DSA-65, and ML-DSA-87 (:rfc:`9881`) public keys and
signatures by default.

.. _v49-0-0:

49.0.0

~~~~~~~~~~~~~~~~~~~

* **BACKWARDS INCOMPATIBLE:** Support for ``x86_64`` macOS has been removed.
We now only publish ``arm64`` wheels for macOS.
* **BACKWARDS INCOMPATIBLE:** Support for 32-bit Windows has been removed.
Users should move to a 64-bit Python installation.
* **BACKWARDS INCOMPATIBLE:** Removed the deprecated
``PUBLIC_KEY_TYPES``, ``PRIVATE_KEY_TYPES``,
``CERTIFICATE_PRIVATE_KEY_TYPES``, ``CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES``,
and ``CERTIFICATE_PUBLIC_KEY_TYPES`` type aliases. Use
``PublicKeyTypes``, ``PrivateKeyTypes``, ``CertificateIssuerPrivateKeyTypes``,
``CertificateIssuerPublicKeyTypes``, and ``CertificatePublicKeyTypes``
instead. These were deprecated in version 40.0.
* **BACKWARDS INCOMPATIBLE:** :class:`~cryptography.hazmat.primitives.ciphers.algorithms.ChaCha20`
now treats the first 4 bytes of the ``nonce`` as a 32-bit little-endian block
counter (as defined in :rfc:`7539`) and tracks the number of bytes processed.
Attempting to encrypt or decrypt more data than the counter allows before it
would overflow now raises a :class:`ValueError` rather than silently diverging
from RFC 7539. Setting the counter portion of the ``nonce`` to zero allows
encrypting up to 256 GiB with a given nonce.
* **BACKWARDS INCOMPATIBLE:** Loading an X.509 certificate whose ECDSA or DSA
signature ``AlgorithmIdentifier`` contains encoded NULL parameters now raises
a :class:`ValueError`. Such certificates are invalid, but older versions of
Java emitted them; previously they loaded with a deprecation warning.
* Fixed cross-compilation of the CFFI bindings when ``PYO3_CROSS_LIB_DIR``
is set. The build now derives the Python include directory from
``PYO3_CROSS_LIB_DIR`` instead of querying the host interpreter, which
previously caused the build to fail during cross-compilations for embedded
systems, on hosts which have same-version Python development headers
installed as the target Python.
* Added support for signing and verifying X.509 certificates, certificate
signing requests, and certificate revocation lists with
:doc:`/hazmat/primitives/asymmetric/mldsa` keys, as well as loading
certificates that contain ML-DSA public keys.
* Added :meth:`~cryptography.hazmat.primitives.hpke.KEM.enc_length` to
:class:`~cryptography.hazmat.primitives.hpke.KEM` so callers can split the
encapsulated key from the ciphertext returned by
:meth:`~cryptography.hazmat.primitives.hpke.Suite.encrypt`.
* :meth:`~cryptography.x509.verification.ExtensionPolicy.require_present`,
:meth:`~cryptography.x509.verification.ExtensionPolicy.may_be_present`, and
:meth:`~cryptography.x509.verification.ExtensionPolicy.require_not_present`
now accept any extension type. Previously only a fixed set of extension
types was supported, which made it impossible to account for otherwise
unrecognized critical extensions during path validation.
* Added support for using :class:`~cryptography.x509.Certificate`,
:class:`~cryptography.x509.CertificateSigningRequest`, and
:class:`~cryptography.x509.CertificateRevocationList` as field types in
:doc:`/hazmat/asn1/index` structures.
* Added :func:`~cryptography.hazmat.asn1.value_set`, a class decorator that
registers an :class:`enum.Enum` subclass as an ASN.1 value set: members
are encoded as their underlying value, and decoding fails if the decoded
value does not match one of the declared members.
* Added :meth:`~cryptography.x509.Name.from_bytes` for parsing a
:class:`~cryptography.x509.Name` from DER bytes, the inverse of
:meth:`~cryptography.x509.Name.public_bytes`.
* Added the ``rsa_padding`` keyword-only parameter to
:meth:`~cryptography.x509.CertificateBuilder.public_key`. Passing the
:class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS` class
(not an instance) encodes an RSA subject public key in the certificate's
``subjectPublicKeyInfo`` with the ``id-RSASSA-PSS`` OID and no
parameters.
* Added external mu (message representative) support to
:doc:`/hazmat/primitives/asymmetric/mldsa` via the
``sign_mu`` and ``verify_mu`` methods, which sign and verify a precomputed
64-byte ``mu`` as defined in FIPS 204.

.. _v48-0-1:

48.0.1

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 4.0.1.

.. _v48-0-0:

48.0.0

~~~~~~~~~~~~~~~~~~~

* **BACKWARDS INCOMPATIBLE:** Support for Python 3.8 has been removed.
``cryptography`` now requires Python 3.9 or later.
* **BACKWARDS INCOMPATIBLE:** Loading an X.509 CRL whose inner
``TBSCertList.signature`` algorithm does not match the outer
``signatureAlgorithm`` now raises ``ValueError``. Previously, such CRLs
were parsed successfully and only rejected during signature validation.
* Added support for :doc:`/hazmat/primitives/asymmetric/mlkem` and
:doc:`/hazmat/primitives/asymmetric/mldsa` when using OpenSSL 3.5.0 or
later, in addition to the existing AWS-LC and BoringSSL support. This means
post-quantum algorithms are now available to users of our wheels.

* **Note:** Going forward, we do not guarantee that all functionality
 in ``cryptography`` will be available when building against
 OpenSSL. See :doc:`/statements/state-of-openssl` for more information.


.. _v47-0-0:

47.0.0

~~~~~~~~~~~~~~~~~~~

* Support for Python 3.8 is deprecated and will be removed in the next
``cryptography`` release.
* **BACKWARDS INCOMPATIBLE:** Support for binary elliptic curves
(``SECT*`` classes) has been removed. These curves are rarely used and
have additional security considerations that make them undesirable.
* **BACKWARDS INCOMPATIBLE:** Support for OpenSSL 1.1.x has been removed.
OpenSSL 3.0.0 or later is now required. LibreSSL, BoringSSL, and AWS-LC
continue to be supported.
* **BACKWARDS INCOMPATIBLE:** Dropped support for LibreSSL < 4.1.
* **BACKWARDS INCOMPATIBLE:** Loading keys with unsupported algorithms or
keys with unsupported explicit curve encodings now raises
:class:`~cryptography.exceptions.UnsupportedAlgorithm` instead of
``ValueError``. This change affects
:func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_der_private_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key`,
:func:`~cryptography.hazmat.primitives.serialization.load_der_public_key`,
and :meth:`~cryptography.x509.Certificate.public_key` when called on
certificates with unsupported public key algorithms.
* **BACKWARDS INCOMPATIBLE:** When parsing elliptic curve private keys, we now
reject keys that incorrectly encode a private key of the wrong length because
such keys are impossible to process in a constant-time manner. We do not
believe keys with this problem are in wide use, however we may revert this
change based on the feedback we receive.
* Deprecated passing 64-bit (8-byte) and 128-bit (16-byte) keys to
:class:`~cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES`. In a
future release, only 192-bit (24-byte) keys will be accepted. Users should
expand shorter keys themselves (e.g., for single DES: ``key + key + key``,
for two-key: ``key + key[:8]``).
* Updated the minimum supported Rust version (MSRV) to 1.83.0, from 1.74.0.
* Support for ``x86_64`` macOS (including publishing wheels) is deprecated
and will be removed in the next release. We will switch to publishing an
``arm64`` only wheel for macOS.
* Support for 32-bit Windows (including publishing wheels) is deprecated
and will be removed in the next release. Users should move to a 64-bit
Python installation.
* ``public_bytes`` and ``private_bytes`` methods on keys now raise
``TypeError`` (instead of ``ValueError``) if an invalid encoding is provided
for the given ``format``.
* Moved :class:`~cryptography.hazmat.decrepit.ciphers.modes.CFB`,
:class:`~cryptography.hazmat.decrepit.ciphers.modes.OFB`, and
:class:`~cryptography.hazmat.decrepit.ciphers.modes.CFB8` into
:doc:`/hazmat/decrepit/index` and deprecated them in the ``modes`` module.
They will be removed from the ``modes`` module in 49.0.0.
* Moved :class:`~cryptography.hazmat.primitives.ciphers.algorithms.Camellia`
into  :doc:`/hazmat/decrepit/index` and deprecated it in the ``cipher`` module.
It will be removed from the ``cipher`` module in 49.0.0.
* Added :meth:`~cryptography.hazmat.primitives.kdf.hkdf.HKDF.extract`
to :class:`~cryptography.hazmat.primitives.kdf.hkdf.HKDF`. The previous
private implementation will be removed in 49.0.0.
* Added support for loading elliptic curve keys that contain explicit encodings
of the curves ``secp256r1``, ``secp384r1``, and ``secp521r1``.
* Added support for :class:`~cryptography.hazmat.primitives.kdf.argon2.Argon2d`
and :class:`~cryptography.hazmat.primitives.kdf.argon2.Argon2i`
when using OpenSSL 3.2.0+.
* Added ``derive_into`` methods to
:class:`~cryptography.hazmat.primitives.kdf.hkdf.HKDF`,
:class:`~cryptography.hazmat.primitives.kdf.hkdf.HKDFExpand`,
:class:`~cryptography.hazmat.primitives.kdf.concatkdf.ConcatKDFHash`,
:class:`~cryptography.hazmat.primitives.kdf.concatkdf.ConcatKDFHMAC`,
:class:`~cryptography.hazmat.primitives.kdf.argon2.Argon2id`,
:class:`~cryptography.hazmat.primitives.kdf.pbkdf2.PBKDF2HMAC`,
:class:`~cryptography.hazmat.primitives.kdf.kbkdf.KBKDFHMAC`,
:class:`~cryptography.hazmat.primitives.kdf.kbkdf.KBKDFCMAC`,
:class:`~cryptography.hazmat.primitives.kdf.scrypt.Scrypt`, and
:class:`~cryptography.hazmat.primitives.kdf.x963kdf.X963KDF` to allow
deriving keys directly into pre-allocated buffers.
* Added ``encrypt_into`` and ``decrypt_into`` methods to
:class:`~cryptography.hazmat.primitives.ciphers.aead.AESCCM`,
:class:`~cryptography.hazmat.primitives.ciphers.aead.AESGCM`,
:class:`~cryptography.hazmat.primitives.ciphers.aead.AESGCMSIV`,
:class:`~cryptography.hazmat.primitives.ciphers.aead.AESOCB3`,
:class:`~cryptography.hazmat.primitives.ciphers.aead.AESSIV`, and
:class:`~cryptography.hazmat.primitives.ciphers.aead.ChaCha20Poly1305` to
allow encrypting directly into a pre-allocated buffer.
* Added support for PKCS1v15 signing without DigestInfo using
:class:`~cryptography.hazmat.primitives.asymmetric.utils.NoDigestInfo`.
* Added :meth:`~cryptography.hazmat.primitives.hashes.Hash.hash`, a one-shot
method for computing hashes.
* Added :doc:`/hazmat/primitives/hpke` support implementing :rfc:`9180` for
hybrid authenticated encryption.
* Added new :doc:`/hazmat/primitives/asymmetric/mlkem` module with
support for ML-KEM key encapsulation with AWS-LC and BoringSSL.

* **Note:** Post-quantum algorithm support requires AWS-LC or BoringSSL.
 As we ship our wheels with OpenSSL, most users will not have access to
 these APIs yet. See :doc:`/statements/state-of-openssl` for more
 information on OpenSSL support.
* Added new :doc:`/hazmat/primitives/asymmetric/mldsa` module with
support for ML-DSA signing and verification with AWS-LC and BoringSSL.

* **Note:** Post-quantum algorithm support requires AWS-LC or BoringSSL.
 As we ship our wheels with OpenSSL, most users will not have access to
 these APIs yet. See :doc:`/statements/state-of-openssl` for more
 information on OpenSSL support.
* Added new :doc:`/hazmat/asn1/index` module with support for declaratively
defining custom ASN.1 types and encoding/decoding them.
* Fixed compilation when using LibreSSL 4.3.0 and OpenSSL 4.0.0.
* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 4.0.0.

.. _v46-0-7:

46.0.7

~~~~~~~~~~~~~~~~~~~

* **SECURITY ISSUE**: Fixed an issue where non-contiguous buffers could be
passed to APIs that accept Python buffers, which could lead to buffer
overflow. **CVE-2026-39892**
* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.6.

.. _v46-0-6:

46.0.6

~~~~~~~~~~~~~~~~~~~

* **SECURITY ISSUE**: Fixed a bug where name constraints were not applied
to peer names during verification when the leaf certificate contains a
wildcard DNS SAN. Ordinary X.509 topologies are not affected by this bug,
including those used by the Web PKI. Credit to **Oleh Konko (1seal)** for
reporting the issue. **CVE-2026-34073**

.. _v46-0-5:

46.0.5

~~~~~~~~~~~~~~~~~~~

* An attacker could create a malicious public key that reveals portions of your
private key when using certain uncommon elliptic curves (binary curves).
This version now includes additional security checks to prevent this attack.
This issue only affects binary elliptic curves, which are rarely used in
real-world applications. Credit to **XlabAI Team of Tencent Xuanwu Lab and
Atuin Automated Vulnerability Discovery Engine** for reporting the issue.
**CVE-2026-26007**
* Support for ``SECT*`` binary elliptic curves is deprecated and will be
removed in the next release.

.. v46-0-4:

46.0.4

~~~~~~~~~~~~~~~~~~~

* `Dropped support for win_arm64 wheels`_.
* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.5.

.. _v46-0-3:

46.0.3

~~~~~~~~~~~~~~~~~~~

* Fixed compilation when using LibreSSL 4.2.0.

.. _v46-0-2:

46.0.2

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.4.

.. _v46-0-1:

46.0.1

~~~~~~~~~~~~~~~~~~~

* Fixed an issue where users installing via ``pip`` on Python 3.14 development
versions would not properly install a dependency.
* Fixed an issue building the free-threaded macOS 3.14 wheels.

.. _v46-0-0:

46.0.0

~~~~~~~~~~~~~~~~~~~

* **BACKWARDS INCOMPATIBLE:** Support for Python 3.7 has been removed.
* Support for OpenSSL < 3.0 is deprecated and will be removed in the next
release.
* Support for ``x86_64`` macOS (including publishing wheels) is deprecated
and will be removed in two releases. We will switch to publishing an
``arm64`` only wheel for macOS.
* Support for 32-bit Windows (including publishing wheels) is deprecated
and will be removed in two releases. Users should move to a 64-bit
Python installation.
* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.3.
* We now build ``ppc64le`` ``manylinux`` wheels and publish them to PyPI.
* We now build ``win_arm64`` (Windows on Arm) wheels and publish them to PyPI.
* Added support for free-threaded Python 3.14.
* Removed the deprecated ``get_attribute_for_oid`` method on
:class:`~cryptography.x509.CertificateSigningRequest`. Users should use
:meth:`~cryptography.x509.Attributes.get_attribute_for_oid` instead.
* Removed the deprecated ``CAST5``, ``SEED``, ``IDEA``, and ``Blowfish``
classes from the cipher module. These are still available in
:doc:`/hazmat/decrepit/index`.
* In X.509, when performing a PSS signature with a SHA-3 hash, it is now
encoded with the official NIST SHA3 OID.

.. _v45-0-7:

45.0.7

~~~~~~~~~~~~~~~~~~~

* Added a function to support an upcoming ``pyOpenSSL`` release.

.. _v45-0-6:

45.0.6

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.2.

.. _v45-0-5:

45.0.5

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.1.

.. _v45-0-4:

45.0.4

~~~~~~~~~~~~~~~~~~~

* Fixed decrypting PKCS8 files encrypted with SHA1-RC4. (This is not
considered secure, and is supported only for backwards compatibility.)

.. _v45-0-3:

45.0.3

~~~~~~~~~~~~~~~~~~~

* Fixed decrypting PKCS8 files encrypted with long salts (this impacts keys
encrypted by Bouncy Castle).
* Fixed decrypting PKCS8 files encrypted with DES-CBC-MD5. While wildly
insecure, this remains prevalent.

.. _v45-0-2:

45.0.2

~~~~~~~~~~~~~~~~~~~

* Fixed using ``mypy`` with ``cryptography`` on older versions of Python.

.. _v45-0-1:

45.0.1

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.5.0.

.. _v45-0-0:

45.0.0

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Support for Python 3.7 is deprecated and will be removed in the next
``cryptography`` release.
* Updated the minimum supported Rust version (MSRV) to 1.74.0, from 1.65.0.
* Added support for serialization of PKCS12 Java truststores in
:func:`~cryptography.hazmat.primitives.serialization.pkcs12.serialize_java_truststore`
* Added :meth:`~cryptography.hazmat.primitives.kdf.argon2.Argon2id.derive_phc_encoded` and
:meth:`~cryptography.hazmat.primitives.kdf.argon2.Argon2id.verify_phc_encoded` methods
to support password hashing in the PHC string format
* Added support for PKCS7 decryption and encryption using AES-256 as the
content algorithm, in addition to AES-128.
* **BACKWARDS INCOMPATIBLE:** Made SSH private key loading more consistent with
other private key loading:
:func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key`
now raises a ``TypeError`` if the key is unencrypted but a password is
provided (previously no exception was raised), and raises a ``TypeError`` if
the key is encrypted but no password is provided (previously a ``ValueError``
was raised).
* Added ``__copy__`` to the
:class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey`,
:class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKey`, and
:class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKey`
abstract base classes.
* We significantly refactored how private key loading (
:func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`
and
:func:`~cryptography.hazmat.primitives.serialization.load_der_private_key`)
works. This is intended to be backwards compatible for all well-formed keys,
therefore if you discover a key that now raises an exception, please file a
bug with instructions for reproducing.
* Added ``unsafe_skip_rsa_key_validation`` keyword-argument to
:func:`~cryptography.hazmat.primitives.serialization.load_ssh_private_key`.
* Added :class:`~cryptography.hazmat.primitives.hashes.XOFHash` to support
repeated :meth:`~cryptography.hazmat.primitives.hashes.XOFHash.squeeze`
operations on extendable output functions.
* Added
:meth:`~cryptography.x509.ocsp.OCSPResponseBuilder.add_response_by_hash`
method to allow creating OCSP responses using certificate hash values rather
than full certificates.
* Extended the :mod:`X.509 path validation <cryptography.x509.verification>` API to
support user-configured extension policies via the
:meth:`PolicyBuilder.extension_policies <cryptography.x509.verification.PolicyBuilder.extension_policies>` method.
* Deprecated the ``subject``, ``verification_time`` and ``max_chain_depth``
properties on :class:`~cryptography.x509.verification.ClientVerifier` and
:class:`~cryptography.x509.verification.ServerVerifier` in favor of a new ``policy`` property.
These properties will be removed in the next release of ``cryptography``.
* **BACKWARDS INCOMPATIBLE:** The
:meth:`VerifiedClient.subject <cryptography.x509.verification.VerifiedClient.subjects>`
property can now be `None` since a custom extension policy may allow certificates
without a Subject Alternative Name extension.
* Changed the behavior when the OpenSSL 3 legacy provider fails to load.
Instead of raising an exception, a warning is now emitted. The
``CRYPTOGRAPHY_OPENSSL_NO_LEGACY`` environment variable can still be used to
disable the legacy provider at runtime.
* Added support for the ``CRYPTOGRAPHY_BUILD_OPENSSL_NO_LEGACY`` environment
variable during build time, which prevents the library from ever attempting
to load the legacy provider.
* Added support for the :class:`~cryptography.x509.PrivateKeyUsagePeriod` X.509 extension.
This extension defines the period during which the private key corresponding
to the certificate's public key may be used.
* Added support for compiling against `aws-lc`_.
* Parsing X.509 structures now more strictly enforces that ``Name`` structures
do not have malformed ASN.1.
* We now publish ``py311`` wheels that utilize the faster ``pyo3::buffer::PyBuffer``
interface, resulting in significantly improved performance for operations
involving small buffers.
* Added :func:`~cryptography.hazmat.primitives.serialization.ssh_key_fingerprint`
for computing fingerprints of SSH public keys.
* Added support for deterministic ECDSA signing via the new keyword-only argument
``ecdsa_deterministic`` in :meth:`~cryptography.x509.CertificateBuilder.sign`,
:meth:`~cryptography.x509.CertificateRevocationListBuilder.sign`
and :meth:`~cryptography.x509.CertificateSigningRequestBuilder.sign`.

.. _v44-0-3:

44.0.3

~~~~~~~~~~~~~~~~~~~

* Fixed compilation when using LibreSSL 4.1.0.

.. _v44-0-2:

44.0.2

~~~~~~~~~~~~~~~~~~~

* We now build wheels for PyPy 3.11.

.. _v44-0-1:

44.0.1

~~~~~~~~~~~~~~~~~~~

* Updated Windows, macOS, and Linux wheels to be compiled with OpenSSL 3.4.1.
* We now build ``armv7l`` ``manylinux`` wheels and publish them to PyPI.
* We now build ``manylinux_2_34`` wheels and publish them to PyPI.

.. _v44-0-0:
Links

Update Django from 4.2.13 to 6.0.7.

Changelog

6.0.7

==========================

*July 7, 2026*

Django 6.0.7 fixes three security issues with severity "low" and one bug in
6.0.6.

CVE-2026-48588: Potential exposure of private data via cached ``Set-Cookie`` response
=====================================================================================

:class:`~django.middleware.cache.UpdateCacheMiddleware` and
:func:`~django.views.decorators.cache.cache_page` avoided caching responses
that set a cookie while varying on ``Cookie`` only when the incoming request
contained no cookies at all. When the request already carried an unrelated
cookie (such as a language or theme preference cookie), the protection did not
apply, allowing a response that sets a session or other sensitive cookie to be
stored in Django's shared cache.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-53877: Heap buffer over-read in ``GDALRaster``
=======================================================

When :class:`~django.contrib.gis.gdal.GDALRaster` was instantiated with a bytes
object representing a raster file, the
:attr:`~django.contrib.gis.gdal.GDALRaster.vsi_buffer` property could over-read
the allocated buffer by approximately 32 bytes. This could result in
information disclosure of adjacent heap memory or, in rare cases, a
segmentation fault. Only rasters stored in GDAL's virtual filesystem were
affected.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-53878: Header injection possibility since ``DomainNameValidator`` accepted newlines in input
=====================================================================================================

:class:`~django.core.validators.DomainNameValidator` accepted newlines in
domain names. If such values were included in HTTP responses, header injection
attacks were possible. Django itself wasn't vulnerable because
:class:`~django.http.HttpResponse` prohibits newlines in HTTP headers.

The vulnerability only affected uses of ``DomainNameValidator`` outside Django
form fields, as ``CharField`` strips newlines by default.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed a regression in Django 6.0 where the PBKDF2 and MD5 password hashers
raised :exc:`UnicodeDecodeError` for :class:`bytes` passwords that were not
valid UTF-8. Passwords supplied as :class:`str` or as UTF-8 :class:`bytes`
are unaffected (:ticket:`37184`).


==========================

6.0.6

==========================

*June 3, 2026*

Django 6.0.6 fixes five security issues with severity "low" and one bug in
6.0.5.

CVE-2026-6873: Signed cookie salt namespace collision
=====================================================

:meth:`~django.http.HttpRequest.get_signed_cookie` derived the signing salt by
concatenating the cookie name (``key``) and ``salt`` arguments. When distinct
name and salt pairs produced the same concatenation, cookies could be accepted
in a context different from the one where they were signed.

Cookies are now signed with an unambiguous salt derivation. For backwards
compatibility, cookies signed by older Django versions are accepted until
Django 7.0. Projects affected by the above ambiguity should set
:setting:`SIGNED_COOKIE_LEGACY_SALT_FALLBACK` to ``False`` to reject older
cookies immediately.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-7666: Potential unencrypted email transmission via ``STARTTLS`` in the SMTP backend
============================================================================================

When using :setting:`EMAIL_USE_TLS`, a failed ``STARTTLS`` handshake could
leave a partially-initialized connection that would subsequently be reused for
sending email without encryption. This can occur with ``fail_silently=True``,
as used by :func:`~django.core.mail.send_mail` and
:class:`~django.middleware.common.BrokenLinkEmailsMiddleware`, among others.
Connections configured with :setting:`EMAIL_USE_SSL` are not affected.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-8404: Potential exposure of private data via case-sensitive ``Cache-Control`` directives
=================================================================================================

:class:`~django.middleware.cache.UpdateCacheMiddleware` and
:func:`~django.views.decorators.cache.cache_page` incorrectly cached responses
marked with private ``Cache-Control`` directives when using mixed or uppercase
values (e.g. ``Private``).

The :func:`~django.views.decorators.cache.cache_control` decorator and
:func:`~django.utils.cache.patch_cache_control` function were not affected,
since they normalize directives to lowercase. This issue only affects responses
where ``Cache-Control`` is set manually.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-35193: Potential exposure of private data via missing ``Vary: Authorization``
======================================================================================

:class:`~django.middleware.cache.UpdateCacheMiddleware` and
:func:`~django.views.decorators.cache.cache_page` decorator allowed responses
to requests bearing an ``Authorization`` header (and without ``Cache-Control:
public``) to be cached. To conform with the existing mechanism for constructing
cache keys, responses to these requests will now :ref:`vary on
<using-vary-headers>` ``Authorization``.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-48587: Potential exposure of private data via whitespace padding in ``Vary`` header
============================================================================================

:class:`~django.middleware.cache.UpdateCacheMiddleware` incorrectly cached
responses whose ``Vary`` header values contained leading or trailing
whitespace. Because ``has_vary_header()`` failed to strip that, a ``Vary: *``
header value with surrounding whitespace was not recognized as containing the
wildcard, causing it to be stored and potentially served from the cache when it
should not have been.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed a bug in Django 6.0 where an alert message on an admin changelist with
``ModelAdmin.list_editable`` referred to the "Run" button by its previous
name (:ticket:`37094`).


==========================

6.0.5

==========================

*May 5, 2026*

Django 6.0.5 fixes three security issues with severity "low" and several bugs
in 6.0.4.

CVE-2026-5766: Potential denial-of-service vulnerability in ASGI requests via file upload limit bypass
======================================================================================================

ASGI requests with a missing or understated ``Content-Length`` header could
bypass the :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` limit, potentially loading
large files into memory and causing service degradation.

As a reminder, Django :ref:`expects a limit to be configured
<user-uploaded-content-security>` at the web server level rather than solely
relying on :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-35192: Session fixation via public cached pages and ``SESSION_SAVE_EVERY_REQUEST``
===========================================================================================

Response headers did not :ref:`vary on <using-vary-headers>` cookies if a
session was not modified, but :setting:`SESSION_SAVE_EVERY_REQUEST` was
``True``. A remote attacker could steal a user's session after that user visits
a cached public page.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-6907: Potential exposure of private data due to incorrect handling of ``Vary: *`` in ``UpdateCacheMiddleware``
=======================================================================================================================

Previously, :class:`~django.middleware.cache.UpdateCacheMiddleware` would
erroneously cache requests where the ``Vary`` header contained an asterisk
(``'*'``). This could lead to private data being stored and served.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed a misplaced ``</div>`` in the
``django/contrib/admin/templates/admin/change_list.html`` template added in
Django 6.0 that could be problematic when overriding the ``pagination`` block
(:ticket:`37029`).

* Fixed a bug in Django 6.0 where deprecation warnings incorrectly skipped
lines from third-party packages prefixed with "django" (:ticket:`37067`).


==========================

6.0.4

==========================

*April 7, 2026*

Django 6.0.4 fixes one security issue with severity "moderate", four security
issues with severity "low", and several bugs in 6.0.3.

CVE-2026-3902: ASGI header spoofing via underscore/hyphen conflation
====================================================================

``ASGIRequest`` normalizes header names following WSGI conventions, mapping
hyphens to underscores. As a result, even in configurations where reverse
proxies carefully strip security-sensitive headers named with hyphens, such a
header could be spoofed by supplying a header named with underscores.

Under WSGI, it is the responsibility of the server or proxy to avoid ambiguous
mappings. (Django's :djadmin:`runserver` was patched in :cve:`2015-0219`.) But
under ASGI, there is not the same uniform expectation, even if many proxies
protect against this under default configuration (including ``nginx`` via
``underscores_in_headers off;``).

Headers containing underscores are now ignored by ``ASGIRequest``, matching the
behavior of :pypi:`Daphne <daphne>`, the reference server for ASGI.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-4277: Privilege abuse in ``GenericInlineModelAdmin``
=============================================================

Add permissions on inline model instances were not validated on submission of
forged ``POST`` data in
:class:`~django.contrib.contenttypes.admin.GenericInlineModelAdmin`.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-4292: Privilege abuse in ``ModelAdmin.list_editable``
==============================================================

Admin changelist forms using
:attr:`~django.contrib.admin.ModelAdmin.list_editable` incorrectly allowed new
instances to be created via forged ``POST`` data.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-33033: Potential denial-of-service vulnerability in ``MultiPartParser`` via base64-encoded file upload
===============================================================================================================

When using ``django.http.multipartparser.MultiPartParser``, multipart uploads
with ``Content-Transfer-Encoding: base64`` that include excessive whitespace
may trigger repeated memory copying, potentially degrading performance.

This issue has severity "moderate" according to the :ref:`Django security
policy <severity-levels>`.

CVE-2026-33034: Potential denial-of-service vulnerability in ASGI requests via memory upload limit bypass
=========================================================================================================

ASGI requests with a missing or understated ``Content-Length`` header could
bypass the :setting:`DATA_UPLOAD_MAX_MEMORY_SIZE` limit when reading
``HttpRequest.body``, potentially loading an unbounded request body into
memory and causing service degradation.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed a regression in Django 6.0 where :func:`~django.contrib.auth.alogin`
and :func:`~django.contrib.auth.alogout` did not respectively set or clear
``request.user`` if it had already been materialized (e.g., by sync
middleware) (:ticket:`37017`).

* Fixed a regression in Django 6.0 in admin forms where
``RelatedFieldWidgetWrapper`` incorrectly wrapped all widgets in a
``<fieldset>`` (:ticket:`36949`).

* Fixed a bug in Django 6.0 where the ``fields.E348`` system check did not
detect name clashes between model managers and
:attr:`~django.db.models.ForeignKey.related_name`\s for non-self-referential
relationships (:ticket:`36973`).


==========================

6.0.3

==========================

*March 3, 2026*

Django 6.0.3 fixes a security issue with severity "moderate", a security issue
with severity "low", and several bugs in 6.0.2.

CVE-2026-25673: Potential denial-of-service vulnerability in ``URLField`` via Unicode normalization on Windows
==============================================================================================================

The :class:`~django.forms.URLField` form field's ``to_python()`` method used
:func:`~urllib.parse.urlsplit` to determine whether to prepend a URL scheme to
the submitted value. On Windows, ``urlsplit()`` performs
:func:`NFKC normalization <python:unicodedata.normalize>`, which can be
disproportionately slow for large inputs containing certain characters.

``URLField.to_python()`` now uses a simplified scheme detection, avoiding
Unicode normalization entirely and deferring URL validation to the appropriate
layers. As a result, while leading and trailing whitespace is still stripped by
default, characters such as newlines, tabs, and other control characters within
the value are no longer handled by ``URLField.to_python()``. When using the
default :class:`~django.core.validators.URLValidator`, these values will
continue to raise :exc:`~django.core.exceptions.ValidationError` during
validation, but if you rely on custom validators, ensure they do not depend on
the previous behavior of ``URLField.to_python()``.

This issue has severity "moderate" according to the :ref:`Django security
policy <severity-levels>`.

CVE-2026-25674: Potential incorrect permissions on newly created file system objects
====================================================================================

Django's file-system storage and file-based cache backends used the process
``umask`` to control permissions when creating directories. In multi-threaded
environments, one thread's temporary umask change can affect other threads'
file and directory creation, resulting in file system objects being created
with unintended permissions.

Django now applies the requested permissions via :func:`~os.chmod` after
:func:`~os.mkdir`, removing the dependency on the process-wide umask.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed :exc:`NameError` when inspecting functions making use of deferred
annotations in Python 3.14 (:ticket:`36903`).

* Fixed :exc:`AttributeError` when subclassing builtin lookups and neglecting
to :ref:`override<tuple-for-params>` ``as_sql()`` to accept any sequence
(:ticket:`36934`).

* Fixed :exc:`TypeError` when deprecation warnings are emitted in environments
importing Django by namespace (:ticket:`36961`).

* Fixed a visual regression where fieldset legends were misaligned in the admin
(:ticket:`36920`).

* Prevented the :data:`django.tasks.signals.task_finished` signal from writing
extraneous log messages when no exceptions are encountered (:ticket:`36951`).


==========================

6.0.2

==========================

*February 3, 2026*

Django 6.0.2 fixes three security issues with severity "high", two security
issues with severity "moderate", one security issue with severity "low", and
several bugs in 6.0.1.

CVE-2025-13473: Username enumeration through timing difference in mod_wsgi authentication handler
=================================================================================================

The ``django.contrib.auth.handlers.modwsgi.check_password()`` function for
:doc:`authentication via mod_wsgi</howto/deployment/wsgi/apache-auth>`
allowed remote attackers to enumerate users via a timing attack.

This issue has severity "low" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2025-14550: Potential denial-of-service vulnerability via repeated headers when using ASGI
==============================================================================================

When receiving duplicates of a single header, ``ASGIRequest`` allowed a remote
attacker to cause a potential denial-of-service via a specifically created
request with multiple duplicate headers. The vulnerability resulted from
repeated string concatenation while combining repeated headers, which
produced super-linear computation resulting in service degradation or outage.

This issue has severity "moderate" according to the :ref:`Django security
policy <severity-levels>`.

CVE-2026-1207: Potential SQL injection via raster lookups on PostGIS
====================================================================

:ref:`Raster lookups <spatial-lookup-raster>` on GIS fields (only implemented
on PostGIS) were subject to SQL injection if untrusted data was used as a band
index.

As a reminder, all untrusted user input should be validated before use.

This issue has severity "high" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-1285: Potential denial-of-service vulnerability in ``django.utils.text.Truncator`` HTML methods
========================================================================================================

``django.utils.text.Truncator.chars()`` and ``Truncator.words()`` methods (with
``html=True``) and the :tfilter:`truncatechars_html` and
:tfilter:`truncatewords_html` template filters were subject to a potential
denial-of-service attack via certain inputs with a large number of unmatched
HTML end tags, which could cause quadratic time complexity during HTML parsing.

This issue has severity "moderate" according to the :ref:`Django security
policy <severity-levels>`.

CVE-2026-1287: Potential SQL injection in column aliases via control characters
===============================================================================

:class:`.FilteredRelation` was subject to SQL injection in column aliases via
control characters, using a suitably crafted dictionary, with dictionary
expansion, as the ``**kwargs`` passed to :meth:`.QuerySet.annotate`,
:meth:`~.QuerySet.aggregate`, :meth:`~.QuerySet.extra`,
:meth:`~.QuerySet.values`, :meth:`~.QuerySet.values_list`, and
:meth:`~.QuerySet.alias`.

This issue has severity "high" according to the :ref:`Django security policy
<severity-levels>`.

CVE-2026-1312: Potential SQL injection via ``QuerySet.order_by`` and ``FilteredRelation``
=========================================================================================

:meth:`.QuerySet.order_by` was subject to SQL injection in column aliases
containing periods when the same alias was, using a suitably crafted
dictionary, with dictionary expansion, used in :class:`.FilteredRelation`.

This issue has severity "high" according to the :ref:`Django security policy
<severity-levels>`.

Bugfixes
========

* Fixed a visual regression in Django 6.0 that caused the admin filter sidebar
to wrap below the changelist when filter elements contained long text
(:ticket:`36850`).

* Fixed a visual regression in Django 6.0 for admin form fields grouped under a
``<fieldset>`` aligned horizontally (:ticket:`36788`).

* Fixed a regression in Django 6.0 where ``auto_now_add`` field values were not
populated during ``INSERT`` operations, due to incorrect parameters passed to
``field.pre_save()`` (:ticket:`36847`).


==========================

6.0.1

==========================

*January 6, 2026*

Django 6.0.1 fixes one data loss bug introduced in Django 5.2 as well as
several other bugs in Django 6.0.

Bugfixes
========

* Fixed a bug in Django 5.2 where data exceeding ``max_length`` was silently
truncated by :meth:`.QuerySet.bulk_create` on PostgreSQL (:ticket:`33647`).

* Fixed a regression in Django 6.0 where :ttag:`querystring` mishandled
multi-value :class:`~django.http.QueryDict` keys, both by only preserving the
last value and by incorrectly handling ``None`` values (:ticket:`36783`).

* Fixed a regression in Django 6.0 that prevented changing the name of a
:class:`~django.db.models.ManyToManyField` from taking effect when applying
migrations (:ticket:`36800`).

* Fixed a bug where management command colorized help (introduced in
Python 3.14) ignored the :option:`--no-color` option and the
:envvar:`DJANGO_COLORS` setting (:ticket:`36376`).

* Fixed a regression in Django 6.0 that caused
:meth:`~django.db.models.query.QuerySet.bulk_create` to crash
when introspecting the connection on SQLite (:ticket:`36818`).

* Fixed a visual regression in Django 6.0 for admin form fields grouped under a
``<fieldset>`` in Safari (:ticket:`36807`).

* Fixed a crash in Django 6.0 caused by infinite recursion when calling
``repr()`` on an unevaluated ``django.utils.csp.LazyNonce`` instance
(:ticket:`36810`).

* Fixed a regression in Django 6.0 where :func:`~django.urls.path` routes
defined using :func:`~django.utils.translation.gettext_lazy` failed to
resolve correctly (:ticket:`36796`).

* Fixed a regression in Django 6.0 where the :attr:`.Widget.use_fieldset`
attribute of :class:`~django.forms.ClearableFileInput` was flipped
from ``False`` to ``True`` (:ticket:`36829`).

* Reverted an undocumented optimization in Django 6.0 that modified permission
:attr:`~django.contrib.auth.models.Permission.name` and
:attr:`~django.contrib.auth.models.Permission.codename` values when renaming
models via a migration. This change could affect unrelated
:class:`~django.contrib.auth.models.Permission` objects (:ticket:`36843`) and
did not report conflicts (:ticket:`36793`).


========================

6.0

========================

*December 3, 2025*

Welcome to Django 6.0!

These release notes cover the :ref:`new features <whats-new-6.0>`, as well as
some :ref:`backwards incompatible changes <backwards-incompatible-6.0>` you
should be aware of when upgrading from Django 5.2 or earlier. We've
:ref:`begun the deprecation process for some features
<deprecated-features-6.0>`.

See the :doc:`/howto/upgrade-version` guide if you're updating an existing
project.

Python compatibility
====================

Django 6.0 supports Python 3.12, 3.13, and 3.14. We **highly recommend**, and
only officially support, the latest release of each series.

The Django 5.2.x series is the last to support Python 3.10 and 3.11.

Third-party library support for older versions of Django
========================================================

Following the release of Django 6.0, we suggest that third-party app authors
drop support for all versions of Django prior to 5.2. At that time, you should
be able to run your package's tests using ``python -Wd`` so that deprecation
warnings appear. After making the deprecation warning fixes, your app should be
compatible with Django 6.0.

.. _whats-new-6.0:

What's new in Django 6.0
========================

Content Security Policy support
-------------------------------

Built-in support for the :ref:`Content Security Policy (CSP) <security-csp>`
standard is now available, making it easier to protect web applications against
content injection attacks such as cross-site scripting (XSS). CSP allows
declaring trusted sources of content by giving browsers strict rules about
which scripts, styles, images, or other resources can be loaded.

CSP policies can now be enforced or monitored directly using built-in tools:
headers are added via the
:class:`~django.middleware.csp.ContentSecurityPolicyMiddleware`, nonces are
supported through the :func:`~django.template.context_processors.csp` context
processor, and policies are configured using the :setting:`SECURE_CSP` and
:setting:`SECURE_CSP_REPORT_ONLY` settings.

These settings accept Python dictionaries and support Django-provided constants
for clarity and safety. For example::

 from django.utils.csp import CSP

 SECURE_CSP = {
     "default-src": [CSP.SELF],
     "script-src": [CSP.SELF, CSP.NONCE],
     "img-src": [CSP.SELF, "https:"],
 }

The resulting ``Content-Security-Policy`` header would be set to:

.. code-block:: text

 default-src 'self'; script-src 'self' 'nonce-SECRET'; img-src 'self' https:

To get started, follow the :doc:`CSP how-to guide </howto/csp>`. For in-depth
guidance, see the :ref:`CSP security overview <security-csp>` and the
:doc:`reference docs </ref/csp>`, which include details about decorators to
override or disable policies on a per-view basis.

Template Partials
-----------------

The :ref:`Django Template Language <template-language-intro>` now supports
:ref:`template partials <template-partials>`, making it easier to encapsulate
and reuse small named fragments within a template file. The new tags
:ttag:`{% partialdef %} <partialdef>` and :ttag:`{% partial %} <partial>`
define a partial and render it, respectively.

Partials can also be referenced using the ``template_namepartial_name`` syntax
with :func:`~django.template.Engine.get_template`,
:func:`~django.shortcuts.render`, :ttag:`{% include %}<include>`, and other
template-loading tools, enabling more modular and maintainable templates
without needing to split components into separate files.

A `migration guide`_ is available if you're updating from the
:pypi:`django-template-partials` third-party package.

.. _migration guide: https://github.com/carltongibson/django-template-partials/blob/main/Migration.md

Background Tasks
----------------

Django now includes a built-in Tasks framework for running code outside the
HTTP request–response cycle. This enables offloading work, such as sending
emails or processing data, to background workers.

The framework provides task definition, validation, queuing, and result
handling. Django guarantees consistent behavior for creating and managing
tasks, while the responsibility for running them continues to belong to
external worker processes.

Tasks are defined using the :func:`~django.tasks.task` decorator::

 from django.core.mail import send_mail
 from django.tasks import task


 task
 def email_users(emails, subject, message):
     return send_mail(subject, message, None, emails)

Once defined, tasks can be enqueued through a configured backend::

 email_users.enqueue(
     emails=["userexample.com"],
     subject="You have a message",
     message="Hello there!",
 )

Backends are configured via the :setting:`TASKS` setting. The :ref:`two
built-in backends <task-available-backends>` included in this release are
primarily intended for development and testing.

Django handles task creation and queuing, but does not provide a worker
mechanism to run tasks. Execution must be managed by external infrastructure,
such as a separate process or service.

See :doc:`/topics/tasks` for an overview and the :doc:`Tasks reference
</ref/tasks>` for API details.

Adoption of Python's modern email API
-------------------------------------

Email handling in Django now uses Python's modern email API, introduced in
Python 3.6. This API, centered around the
:class:`email.message.EmailMessage` class, offers a cleaner and
Unicode-friendly interface for composing and sending emails. It replaces use of
Python's older legacy (``Compat32``) API, which relied on lower-level MIME
classes (from :mod:`email.mime`) and required more manual handling of
message structure and encoding.

Notably, the return type of the :meth:`EmailMessage.message()
<django.core.mail.EmailMessage.message>` method is now an instance of Python's
:class:`email.message.EmailMessage`. This supports the same API as the
previous ``SafeMIMEText`` and ``SafeMIMEMultipart`` return types, but is not an
instance of those now-deprecated classes.

Minor features
--------------

:mod:`django.contrib.admin`
~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The Font Awesome Free icon set (version 6.7.2) is now used for the admin
interface icons.

* The new :attr:`.AdminSite.password_change_form` attribute allows customizing
the form used in the admin site password change view.

* Message levels ``messages.DEBUG`` and ``messages.INFO`` now have distinct
icons and CSS styling. Previously, both levels shared the same appearance as
``messages.SUCCESS``. Given that :meth:`.ModelAdmin.message_user` uses
``messages.INFO`` by default, set the level to ``messages.SUCCESS`` to keep
the previous icon and styling.

:mod:`django.contrib.auth`
~~~~~~~~~~~~~~~~~~~~~~~~~~

* The default iteration count for the PBKDF2 password hasher is increased from
1,000,000 to 1,200,000.

:mod:`django.contrib.gis`
~~~~~~~~~~~~~~~~~~~~~~~~~

* The new :attr:`.GEOSGeometry.hasm` property checks whether the geometry has
the M dimension.

* The new :class:`~django.contrib.gis.db.models.functions.Rotate` database
function rotates a geometry by a specified angle around the origin or a
specified point.

* The new :attr:`.BaseGeometryWidget.base_layer` attribute allows specifying a
JavaScript map base layer, enabling customization of map tile providers.

* :lookup:`coveredby` and :lookup:`isvalid` lookups,
:class:`~django.contrib.gis.db.models.Collect` aggregation, and
:class:`~django.contrib.gis.db.models.functions.GeoHash` and
:class:`~django.contrib.gis.db.models.functions.IsValid` database functions
are now supported on MariaDB 12.0.1+.

* The new :lookup:`geom_type` lookup and
:class:`GeometryType() <django.contrib.gis.db.models.functions.GeometryType>`
database function allow filtering geometries by their types.

* Widgets from :mod:`django.contrib.gis.forms.widgets` now render without
inline JavaScript in templates. If you have customized any geometry widgets
or their templates, you may need to :ref:`update them
<geometry-widgets-customization>` to match the new layout.

:mod:`django.contrib.postgres`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* The new :class:`Lexeme <django.contrib.postgres.search.Lexeme>` expression
for full text search provides fine-grained control over search terms.
``Lexeme`` objects automatically escape their input and support logical
combination operators (``&``, ``|``, ``~``), prefix matching, and term
weighting.

* Model fields, indexes, and constraints from :mod:`django.contrib.postgres`
now include system checks to verify that ``django.contrib.postgres`` is an
installed app.

* The :class:`.CreateExtension`, :class:`.BloomExtension`,
:class:`.BtreeGinExtension`, :class:`.BtreeGistExtension`,
:class:`.CITextExtension`, :class:`.CryptoExtension`,
:class:`.HStoreExtension`, :class:`.TrigramExtension`, and
:class:`.UnaccentExtension` operations now support the optional ``hints``
parameter. This allows providing database hints to database routers to assist
them in :ref:`making routing decisions <topics-db-multi-db-hints>`.

:mod:`django.contrib.staticfiles`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
ensures consistent path ordering in manifest files, making them more
reproducible and reducing unnecessary diffs.

* The :djadmin:`collectstatic` command now reports only a summary for skipped
files (and for deleted files when using ``--clear``) at ``--verbosity`` 1. To
see per-file details for either case, set ``--verbosity`` to 2 or higher.

Email
~~~~~

* The new ``policy`` argument for :meth:`EmailMessage.message()
<django.core.mail.EmailMessage.message>` allows specifying the email policy,
the set of rules for updating and serializing the representation of the
message. Defaults to :data:`email.policy.default`.

* :meth:`EmailMessage.attach() <django.core.mail.EmailMessage.attach>` now
accepts a :class:`~email.message.MIMEPart` object from Python's modern email
API.

Internationalization
~~~~~~~~~~~~~~~~~~~~

* Added support and translations for the Haitian Creole language.

Management Commands
~~~~~~~~~~~~~~~~~~~

* The :djadmin:`startproject` and :djadmin:`startapp` commands now create the
custom target directory if it doesn't exist.

* Common utilities, such as ``django.conf.settings``, are now automatically
imported to the :djadmin:`shell` by default.

Migrations
~~~~~~~~~~

* Squashed migrations can now themselves be squashed before being transitioned
to normal migrations.

* Migrations now support serialization of :class:`zoneinfo.ZoneInfo` instances.

* Serialization of deconstructible objects now supports keyword arguments with
names that are not valid Python identifiers.

Models
~~~~~~

* :doc:`Constraints </ref/models/constraints>` now implement a ``check()``
method that is already registered with the check framework.

* The new ``order_by`` argument for :class:`~django.db.models.Aggregate` allows
specifying the ordering of the elements in the result.

* The new :attr:`.Aggregate.allow_order_by` class attribute determines whether
the aggregate function allows passing an ``order_by`` keyword argument.

* The new :class:`~django.db.models.StringAgg` aggregate returns the input
values concatenated into a string, separated by the ``delimiter`` string.
This aggregate was previously supported only for PostgreSQL.

* The :meth:`~django.db.models.Model.save` method now raises a specialized
:exc:`Model.NotUpdated <django.db.models.Model.NotUpdated>` exception, when
:ref:`a forced update <ref-models-force-insert>` results in no affected rows,
instead of a generic :exc:`django.db.DatabaseError`.

* :meth:`.QuerySet.raw` now supports models with a
:class:`~django.db.models.CompositePrimaryKey`.

* Subqueries returning a :class:`~django.db.models.CompositePrimaryKey` can now
be used as the target of lookups other than ``__in``, such as ``__exact``.

* :class:`~django.db.models.JSONField` now supports
:ref:`negative array indexing <key-index-and-path-transforms>` on SQLite.

* The new :class:`~django.db.models.AnyValue` aggregate returns an arbitrary
value from the non-null input values. This is supported on SQLite, MySQL,
Oracle, and PostgreSQL 16+.

* :class:`~django.db.models.GeneratedField`\s and :ref:`fields assigned
expressions <avoiding-race-conditions-using-f>` are now refreshed from the
database after :meth:`~django.db.models.Model.save` on backends that support
the ``RETURNING`` clause (SQLite, PostgreSQL, and Oracle). On backends that
don't support it (MySQL and MariaDB), the fields are marked as deferred to
trigger a refresh on subsequent accesses.

* Using a :ref:`ForeignObject <cpk-and-relations>` with multiple
``from_fields`` in Model indexes, constraints, or :attr:`unique_together
<django.db.models.Options.unique_together>` now emits a system check error.

Pagination
~~~~~~~~~~

* The new :class:`~django.core.paginator.AsyncPaginator` and
:class:`~django.core.paginator.AsyncPage` provide async implementations of
:class:`~django.core.paginator.Paginator` and
:class:`~django.core.paginator.Page` respectively.

Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~

* Multiple ``Cookie`` headers are now supported for HTTP/2 requests when
running with ASGI.

Templates
~~~~~~~~~

* The new variable ``forloop.length`` is now available within a :ttag:`for`
loop.

* The :ttag:`querystring` template tag now consistently prefixes the returned
query string with a ``?``, ensuring reliable link generation behavior.

* The :ttag:`querystring` template tag now accepts multiple positional
arguments, which must be mappings, such as :class:`~django.http.QueryDict`
or :class:`dict`.

Tests
~~~~~

* The :class:`.DiscoverRunner` now supports parallel test execution on systems
using the ``forkserver`` :mod:`multiprocessing` start method.

.. _backwards-incompatible-6.0:

Backwards incompatible changes in 6.0
=====================================

Database backend API
--------------------

This section describes changes that may be needed in third-party database
backends.

* :class:`~django.db.backends.base.schema.BaseDatabaseSchemaEditor` and
PostgreSQL backends no longer use ``CASCADE`` when dropping a column.

* ``DatabaseOperations.return_insert_columns()`` and
``DatabaseOperations.fetch_returned_insert_rows()`` methods are renamed to
``returning_columns()`` and ``fetch_returned_rows()``, respectively, to
denote they can be used in the context of ``UPDATE … RETURNING`` statements
as well as ``INSERT … RETURNING``.

* The ``DatabaseOperations.fetch_returned_insert_columns()`` method is removed
and the ``fetch_returned_rows()`` method replacing
``fetch_returned_insert_r

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant