Skip to content

Conversation

ruanpotgieter95
Copy link

@ruanpotgieter95 ruanpotgieter95 commented Aug 11, 2025

Hi I started to use TextHMACField ( need the key to make it more secure ) for hashing. What I found was that the key isn't being used. When looking at the code I believe the implementation for using the key was swapped between TextDigestField and TextHMACField.

The SQL for the two above classes look like this:

DIGEST_SQL = "digest(%s, 'sha512')"
HMAC_SQL = "hmac(%s, '{}', 'sha512')"

As you can see the HMAC is using the PGCRYPTO extensions hmac function that takes in a key '{}'. Where digest can't.

You can see that the implementation to get_encrypt_sql is in the TextDigestField class and not in the TextHMACField.

class TextDigestField(HashMixin, models.TextField):
    """Text digest field for postgres."""
    encrypt_sql = DIGEST_SQL

    def get_encrypt_sql(self, connection):
        """Get encrypt sql."""
        return self.encrypt_sql.format(get_setting(connection, 'PGCRYPTO_KEY'))

class TextHMACField(HashMixin, models.TextField):
    """Text HMAC field for postgres."""
    encrypt_sql = HMAC_SQL

This makes it that the TextHMACField will never have the key used. When you want to hash a value in plain SQL to check the where clause, you will need to add '{}' as the key for it to work.

The fix is as simple as moving the get_encrypt_sql into TextHMACField. I have tested this locally and it is working as expected.

class TextHMACField(HashMixin, models.TextField):
    """Text HMAC field for postgres."""
    encrypt_sql = HMAC_SQL

    def get_encrypt_sql(self, connection):
        """Get encrypt sql."""
        return self.encrypt_sql.format(get_setting(connection, 'PGCRYPTO_KEY'))

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