Opened 4 years ago

Closed 2 years ago

#18350 closed Bug (duplicate)

Incorrect behavior when inadvertently building a query using two different models.

Reported by: django@… Owned by: nobody
Component: Database layer (models, ORM) Version: 1.4
Severity: Normal Keywords: query model incorrect behavior
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Consider the following code:

class Vulnerability(models.Model):
	class Meta:
		unique_together = ("client","name")
	client = models.ForeignKey(Client)
	name = models.CharField(max_length=MAX_CHAR_LENGTH)
	desc = models.CharField(max_length=MAX_CHAR_LENGTH, blank=True)
class Client(models.Model):
	name = models.CharField(max_length=MAX_CHAR_LENGTH,unique=True)
class ClientUser(models.Model):
	class Meta:
	user = models.ForeignKey(User)
	client = models.ForeignKey(Client)

An attempt to create a query incorrectly referencing a different model actually succeeds:

In [29]: u = User.objects.get(id=1)
In [30]: x = Vulnerability.objects.filter(client__clientuser = u)   # this should be client__clientuser__user

In [31]: x.query.sql_with_params()
Out[31]: ('SELECT "qtm_vulnerability"."id", "qtm_vulnerability"."client_id", "qtm_vulnerability"."name", "qtm_vulnerability"."desc" FROM "qtm_vulnerability" INNER JOIN "qtm_client" ON ("qtm_vulnerability"."client_id" = "qtm_client"."id") INNER JOIN "qtm_clientuser" ON ("qtm_client"."id" = "qtm_clientuser"."client_id") WHERE "qtm_clientuser"."id" = %s ',(1,))

What's happening here is that the PK for u (1) is being passed as the PK for ClientUser in the query. This will return unexpected and possibly dangerous* results for every ClientUser whose PK does not equal its user attribute PK.

*dangerous in that if you're using ClientUser and its associated User relationship to govern access to specific data, you will get unexpected results with this query and no error to show that you've made a mistake.

More correct behavior would be to detect that you're creating a query relationship for a model using a PK from a different model, and throw an error (or at least a warning).

Change History (3)

comment:1 Changed 3 years ago by lukeplant

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I was sure I'd seen this bug reported elsewhere, but perhaps it was just a similar one regarding setting attributes to incorrect models. Accepting regardless, we can mark as a dupe if we find the dupe.

comment:2 Changed 2 years ago by anonymous

I just got bitten by this bug again (different project). Is there a fix possible?

comment:3 Changed 2 years ago by timo

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #14334

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