Opened 3 weeks ago

Closed 2 weeks ago

#37433 closed Cleanup/optimization (fixed)

Escaped database error messages logged by `Q.check()`

Reported by: Natalia Bidart Owned by: Natalia Bidart
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: not-security
Cc: Jake Howard, David Smith Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Q.check(), used by CheckConstraint.validate() and by UniqueConstraint.validate() with a condition, catches DatabaseError and logs it to the django.db.models logger:

logger.warning("Got a database error calling check() on %r: %s", self, e)

Database error messages can include the values being validated, which may originate from user input (for example through ModelForm validation). These messages are currently logged as-is. For defense in depth, and for consistency with other logging call sites, Q.check() should log the message through django.utils.log.log_message() so that its content is escaped, and trim it to a reasonable length.

The trimming logic for large values is currently duplicated in django/views/debug.py and django/contrib/gis/gdal/raster/source.py. A small trim_value() helper in django.utils.text could be shared by those two places and by Q.check().

Separately, the fact that BaseConstraint.validate() treats a constraint as satisfied when evaluating it raises a database error (logging a warning and leaving the error to surface on save()) is not documented. A short note in the constraints reference would help developers understand why a condition that can fail to evaluate does not act as validation.

Change History (8)

comment:1 by Natalia Bidart, 3 weeks ago

Cc: Jake Howard added
Keywords: not-security added

comment:2 by David Smith, 3 weeks ago

Triage Stage: Unreviewed → Accepted

comment:3 by Natalia Bidart, 2 weeks ago

Has patch: set

comment:4 by Natalia Bidart, 2 weeks ago

Cc: David Smith added

comment:5 by Jacob Walls, 2 weeks ago

Patch needs improvement: set

comment:6 by Jacob Walls, 2 weeks ago

Patch needs improvement: unset
Triage Stage: Accepted → Ready for checkin

comment:7 by nessita <124304+nessita@…>, 2 weeks ago

In 7d89d63:

Refs #37433 -- Added django.utils.text.trim_value() helper.

The debug page and the raster lookup check each trimmed large values
to 4096 characters with their own copy of the same code. The shared
helper also corrects the suffix, which reported characters as bytes
and showed the original length as if it were the amount trimmed.

The trimmed value and the suffix are returned separately so callers
can escape the value without escaping the suffix.

Refs #34746.

comment:8 by nessita <124304+nessita@…>, 2 weeks ago

Resolution: → fixed
Status: assigned → closed

In 5190bbc3:

Fixed #37433 -- Escaped database error messages logged by Q.check().

Database error messages can include the values being validated, which
may originate from user input. Logging them through log_message()
escapes their content and keeps large values trimmed, consistent with
other logging call sites.

Thanks Jacob Walls for reviews.

Note: See TracTickets for help on using tickets.
Back to Top