CVE-2023-46128 (Python, published 2023-10-25T18:17Z)
Description: value: Nautobot is a Network Automation Platform built as a web application atop the Django Python framework with a PostgreSQL or MySQL database. In Nautobot 2.0.x, certain REST API endpoints, in combination with the `?depth=<N>` query parameter, can expose hashed user passwords as stored in the database to any authenticated user with access to these endpoints. The passwords are not exposed in plaintext. This vulnerability has been patched in version 2.0.3.


Severity: nan (CVSS v3 base score: 6.5)
Weakness: CWE-312 \u2014 Cleartext Storage of Sensitive Information
The product stores sensitive information in cleartext within a resource that might be accessible to another control sphere.
Repository: https://github.com/nautobot/nautobot
Files changed:
changes/4692.fixed
changes/4692.housekeeping
changes/4692.security
nautobot/core/api/utils.py
nautobot/core/testing/api.py
nautobot/docs/development/apps/migration/code-updates.md
Commit message: Fix `Meta` inheritance in nested serializer classes (#4692)

* Add test coverage

* Fix issue

* Change fragment

* Add more change fragments

* Refine test implementation

* Add reference to GHSA

* Add admonition about use of fields = __all__ on serializers

* Add PR number

Vulnerable code:
            class Meta:
                model = relation_info.related_model
                if hasattr(base_serializer_class.Meta, "fields"):
                    fields = base_serializer_class.Meta.fields
                if hasattr(base_serializer_class.Meta, "exclude"):
                    exclude = base_serializer_class.Meta.exclude
                            # The response should be a brief API object, containing an ID, object_type, and URL ending in the UUID of the relevant object

Fixed code:
Fixed incorrect inheritance of `Meta` attributes into nested serializers (`depth >= 1`).
Added check in REST API generic test cases to detect strings like `password` and `sha256` that shouldn't generally appear in REST API responses.
Fixed potential exposure of hashed user password data on certain REST API endpoints when using the `?depth=1` query parameter. For more details, please refer to [GHSA-r2hw-74xv-4gqp](https://github.com/nautobot/nautobot/security/advisories/GHSA-r2hw-74xv-4gqp).
            class Meta(base_serializer_class.Meta):
    VERBOTEN_STRINGS = (
        "password",
        # https://docs.djangoproject.com/en/3.2/topics/auth/passwords/#included-hashers
        "argon2",
        "bcrypt",
        "crypt",
        "md5",
        "pbkdf2",
        "scrypt",
        "sha1",
        "sha256",
        "sha512",
    )

    def assert_no_verboten_content(self, response):
        """
        Check an API response for content that should not be exposed in the API.

        If a specific API has a false failure here (maybe it has security-related strings as model flags or something?),
        its test case should overload self.VERBOTEN_STRINGS appropriately.
        """
        response_raw_content = response.content.decode(response.charset)
        for verboten in self.VERBOTEN_STRINGS:
            self.assertNotIn(verboten, response_raw_content)

            # Content that should never be present:
            self.assert_no_verboten_content(response)
            self.assert_no_verboten_content(response)
                            # The response should be a brief API object, containing an ID, object_type, and a
                            # URL ending in the UUID of the relevant object:
            self.assert_no_verboten_content(response)
            self.assert_no_verboten_content(response)
!!! warning
    Use caution around `fields = "__all__"` -- if your model has any fields that should _not_ be exposed in the REST API, you should avoid using `"__all__"` and instead use an explicit `fields` list to ensure that such fields are not exposed. In some cases, it may be appropriate to use `"__all__"` in combination with flags such as `write_only=True` on specific fields, but proceed with caution and examine the REST API data carefully to ensure that its contents are as expected.