There is an argument to be made for not using force_bytes, but there is 
also a semantic difference between “force” and “to”. I wouldn’t think it 
would be possible to change force_bytes to throw an exception without 
serious compatibility issues - str() is how lazy objects are resolved IIRC, 
and there are numerous other places it is called with arguments that need 
to be cast to a string.

The behavior of the make_password method is quite surprising to be honest, 
and maybe the advantages of being able to pass any object into the method 
is entirely academic because nobody passes anything but strings on purpose. 
On the other hand this is the first post I can remember about this. 

On Thursday, 12 March 2020 19:55:46 UTC, Dawid Czeluśniak wrote:
>
> Tom,
>
> I believe that I found the root cause of this issue. Let's take a closer 
> look at force_bytes 
> <https://github.com/django/django/blob/master/django/utils/encoding.py#L82> 
> function from Django and to_bytes 
> <https://github.com/pallets/werkzeug/blob/master/src/werkzeug/_compat.py#L195>
>  
> function from Werkzeug (just for comparison). There is one *fundamental* 
> difference 
> between these: force_bytes from Django fallbacks to string representation 
> of the object whereas to_bytes from Werkzeug raises TypeError if it can't 
> cast the value to bytes. That's why when calling make_password with 
> object that can't be "easily" cast to bytes returns a generated hash:
>
> In [1]: from django.contrib.auth.hashers import make_password
>
> In [2]: make_password([1, 2, 3])
> Out[2]: 
> 'pbkdf2_sha256$180000$Y9azq0uVWSoh$E7O13LefzP1I4MylXfFYKDkgCnZen6tf+FAblnBYssQ='
>
> whereas generate_password_hash from Werkzeug raises TypeError:
>
> In [16]: from werkzeug.security import generate_password_hash
>
> In [17]: generate_password_hash([1, 2, 3])
> TypeError: Expected bytes
>
> IMHO throwing an exception is a more reasonable approach.
>
> Anyway, thank you for your help :)
> Dawid
>
> On Thursday, 12 March 2020 19:17:15 UTC+1, Tom Forbes wrote:
>>
>> In this context it means that you shouldn’t encrypt, hash or otherwise 
>> manipulate the password before passing it into the method. 
>>
>> Django, many other packages and Python itself will accept objects that 
>> can be coerced into a string (via __str__) rather than throw an exception. 
>> We’re all consenting adults here - if you want to pass a non-string object 
>> into “make_password” then that’s up to you.
>>
>> The question really is if this is a common enough mistake to warrant a 
>> guard against strange input. I’d say no, however a small change to the 
>> documentation might be in order.
>>
>> Tom
>>
>> On 12 Mar 2020, at 17:41, Dawid Czeluśniak <czelusn...@gmail.com> wrote:
>>
>> Adam,
>>
>> If it's perfectly fine to pass almost any not-None object to 
>> make_password function and it returns correctly generated hash then why 
>> does the documentation say:
>>
>> make_password(password, salt=None, hasher='default')
>>> Creates a hashed password in the format used by this application. It 
>>> takes one mandatory argument: the password in *plain-text*.
>>
>>  
>>
>> https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#django.contrib.auth.hashers.make_password
>>
>> What does "plain-text" mean there?
>>
>> Thanks,
>> Dawid
>>
>>
>>
>> On Thursday, 12 March 2020 18:18:59 UTC+1, Adam Johnson wrote:
>>>
>>> User provided passwords are validated already: 
>>> https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#module-django.contrib.auth.password_validation
>>>
>>> When using set_password directly, you as the programmer are responsible 
>>> for ensuring the value you use for password is valid. Normally this means 
>>> calling the functions detailed in "Integrating validation" beforehand.
>>>
>>> -- 
>>> Adam
>>>
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers (Contributions to Django itself)" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to django-d...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/django-developers/bda75e4c-2dae-42ef-91f3-c3054031c800%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/django-developers/bda75e4c-2dae-42ef-91f3-c3054031c800%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/c36ce153-4464-4fac-b620-a2c9a2d80e2f%40googlegroups.com.
  • ... Dawid Czeluśniak
    • ... Adam Johnson
    • ... Ethem Güner
    • ... '1337 Shadow Hacker' via Django developers (Contributions to Django itself)
      • ... Adam Johnson
        • ... Dawid Czeluśniak
          • ... Tom Forbes
            • ... Dawid Czeluśniak
              • ... Tom Forbes
                • ... Dawid Czeluśniak
                • ... Adam Johnson
                • ... Dawid Czeluśniak
    • ... Dawid Czeluśniak
      • ... Mentor Carranza Carranza
      • ... Florian Apolloner
        • ... charettes
        • ... Mariusz Felisiak
          • ... Florian Apolloner

Reply via email to