#Password security problem in Django

106 messages · Page 1 of 1 (latest)

warm ember
#

Hi. I logged in to Django admin. I wanted to look at the security measures in my browser (Firefox developer edition). I saw my password sitting there like a pumpkin. Why wasn't any action taken for this problem?

With Turkish.

Selam. Django adminde üyelik oturumu açtım. Tarayıcımdaki (Firefox developer edition) güvenlik önlemlerine bakmak istedim. Şifremin kabak gibi orada durduğunu gördüm. Bu soruna niye bir önlem alınmadı?

warm ember
#

In network infos

localhost:8000/admin/login/?next=/admin/

  • csrfmiddlewaretoken "WTQ5xd...2vL2cdwB"
  • username "djangouser"
  • password "1234"
  • next "/admin/"
ornate nimbus
#

Ok, so?

#

That's how it's always done

warm ember
#

Malicious people obtain this information on the business network or computer.

ornate nimbus
#

How?

warm ember
#

A security expert noticed this issue in Django. He said it shouldn't happen like this.

ornate nimbus
#

His an idiot

#

You use HTTPS to encrypt traffic

#

Then attacker needs to break it

warm ember
#

He works in virtual security for the government

#

He states that no precautions have been taken for the local network, not the Internet. He says it's a big problem.

ornate nimbus
#

Django doesn't know anything about local network or internet

#

It accepts a POST request

vague flower
#

Passwords need to be sent to authenticate users. That's perfectly normal and a non-issue.
If you are worried about this not being secure enough, you may add extra security features like one-time passwords and multi-factor authentication.

#

If your app is available on a local network, you may want to configure a web server with TLS encryption.

ornate nimbus
#

internet local network whatever - it's outside of django scope. As said again - sure use https to encrypt trafic

#

you will still see password in you dev tools

#

because you see it from one end before encryption

vague flower
#

Yeah, the browser sort of needs to know it 😄

ornate nimbus
#

and django will see it

#

but between browser and webserver that terminates https (e,g, nginx) it's secure enough

warm ember
#

Why isn't this transaction converted into a token and sent to the server where the password is written? As soon as you type the password... Not the password we wrote with the post method, but the hidden form of the password we wrote should be sent to the server. In this case, how will the browser keep and read the password? There are tokens now...

#

password input
write your password
translate to security token
ready
press "login" button!

TA TA!!!

#

But no security!

ornate nimbus
#

Because it doesn't add security?

#

It only hides real password from server

warm ember
#

Default Django Admin login page!!! ?

ornate nimbus
#

Whole django auth system works like that

#

as most of the internet

civic mirage
# warm ember A security expert noticed this issue in Django. He said it shouldn't happen like...

In order for the client to authenticate, some data has to be sent to the server for it to validate.
There are cryptographic schemes which actually revolve around not actually sending what you're trying to communicate and generate a binary decision from fragments of information (similar to Zero Knowledge based proofs https://en.wikipedia.org/wiki/Zero-knowledge_proof) - those aren't commonly used for server - client communication in the web though, maybe in some transport level encryption, but not applicable here

What a security expert may be interested in, is how that password gets stored at rest, and checked (the checking validation can be quite complicated, as you want to have some random sleep timers before sending the response in either case depending on the cryptographic algorithm)

If you're using Django's AbstractUser, or any base model of it, you've got some nice things built in for handling password storage and validation which is considered secure (enough) for most cases and is also being scrutinized by professionals

If you're in a company which utilizes SSO for everything, it may make a lot more sense to look at implementing SSO, as you then don't have to keep ANY credentials within your app

civic mirage
#

If somebody was capable of decryping your SSL traffic, you're in a lot more trouble

Even if that person couldn't get the password, you'd still not gain ANYTHING, as they can just manipulate your requests and the server's responses

ornate nimbus
#

I wonder if hashing password client-side do have some benefits like keeping it more safe in case of malicious server (but why it would then let client hash it?) or case of DB leak. But yeah, it doesn't add real security in communication

civic mirage
# ornate nimbus I wonder if hashing password client-side do have some benefits like keeping it m...

Its really not helping anyone, as the hashed version essentially becomes your password

You can do whatever you want to the password client-side, you are just more likely to produce less secure versions of your password

Although there are cryptographic ways to alleviate this issue completely, i have yet to actually see them being implemented in any system. Plus they would revolve around the client having to store more than just a small password, but rather maintain a certificate and store the server token as well.

Its simply not worth the trouble it seems, even for high risk systems. The authentication mechanisms aren't the issue, the user seems to be the biggest attack vector these days.

ornate nimbus
#

I see, thanks for your input

warm ember
#

I know places that implement this security. I saw.

ornate nimbus
#

Anyway idea is that if you need security in any given network - invest time into setting up good TLS

civic mirage
warm ember
#

Someone living in my house can press f12 and get these passwords. Are you crazy?

civic mirage
warm ember
#

{
"encTridField": "UFsd....Erkg7IM=",
"tridField": "",
"egpField": "",
"encEgpField": "U2F.....lofJMk=",
"currentPageToken": "0949.....264b",
"actionName": "giris",
"submitButton": "Giriş+Yap"
}

civic mirage
#

I'd strongly recommend deleing that, if that is actually your login data

warm ember
#

This is when login info.

civic mirage
#

Please delete that message.

warm ember
civic mirage
#

Alright, just making sure

#

If somebody has the full payload of your authentication, they could authenticate

warm ember
#

As you can see, I showed you a security measure in progress. Django does not have this measure.

civic mirage
#

That doesn't protect you from anything essentially

The data that is sent from the client (whatever that is, however it was derived doesn't matter) becomes your authentication information.

warm ember
#

It's a truly worrying omission.

#

People produce and operate different tokens every time you log in.

civic mirage
#

I'd heavily recommend that you read up on web security

What you're describing is a logical misstep as far as i can tell.

Regardless if it makes sense or not, you can always replace the authentication in django with your own stuff:
https://docs.djangoproject.com/en/5.0/topics/auth/customizing/

warm ember
#

What do you mean it's useless?

#

My password stored on the server is a token. However, my password sent to the server is a naked doll.

civic mirage
# warm ember People produce and operate different tokens every time you log in.

That still doesn't matter.
Even if the payload is tagged with a time, you are still VERY much vulnerable to the attack you've described

It just lessens the time window for an attacker (which, granted, is a good thing, but still, if somebody is at your PC - or has been in the past - that is able to install any piece of software, or the communication channel between you and the server is compromised you've still lost the battle.)

civic mirage
warm ember
#

You don't ask and answer people like ChatGPT, do you?

civic mirage
warm ember
#

Even though Django salts on storage, it does not salt on login.

civic mirage
#

(A salt is merely a random string of characters which is composed with a secret shortly before hashing - and is then stored in cleartext along with the secret. It attempts to protect from rainbow tables and several other preparation based attacks)

warm ember
#

I'm asked to do this. Django will tire me out for nothing. What kind of a framework is it... 😄

#

I have to change everything, down to Django's ready-made login structure, and I'm a junior developer. What a shame... Have pity on me. 😄

civic mirage
#

The default makes sense and is the way for example banks and 90% of the internet does it.

It has been under scrutiny over years by quite a few security pentesters without much trouble.

If you need something substandard, you are probably going to have to build it yourself. However, Django helpfully gives you the tools to do so

civic mirage
#

If you're doing this for a company, ask if the company is already using SSO for authentication, maybe you don't have to handle authentication at all :P

warm ember
#

It would be nice if Django did this "I don't need to bother" step. Why should I put my foot down for every business? 😄

civic mirage
warm ember
#

Why would it be unnecessary to take Django security one step further in this respect? I would be happy if this update is made before we see Django 5.1.

civic mirage
warm ember
#

I think what you say will be rejected by senior security experts. It seems that I will receive security training on these issues and do my own work. Nevermind, no problem. I hope I can find my way with the work I do.

#

Thnks.

civic mirage
# warm ember https://turkiye.gov.tr

Btw

What they're doing is beyond laughable

I wanted to see what they actually do on the client

They're encrypting your password with the same key, every. single. time. Its right there

Actually, they've made their site even less secure, jCryption seems to be a dotNET library with javascript counterparts

We therefore know that they're using ASP.NET in the backend (Its not terrible that we can know this stuff, but they had no reason to tell us, and yet here we are :P)

warm ember
civic mirage
# warm ember How to do it better? How to do what should be done?

Depends, what specifically do you want to achieve?
The way they're doing this is definitely not the right one

Like i've said, the django defaults are sane. Why change what isn't broken?

What specifically do you want to achieve?

If you just want to increase your site's security, consider other ways, like multi factor authentication, there are a couple of libraries to help you achive that task, like django-two-factor-auth:
https://github.com/jazzband/django-two-factor-auth

There are countless things to increase the perception, and the actual security of any system. You need to be more specific about from what you're trying to protect from.
There is also the security topic in the django docs which try to show you some attack vectors, what django does by default to help you, and what you could've possibly done insecurely
https://docs.djangoproject.com/en/5.0/topics/security/

warm ember
# civic mirage Depends, what specifically do you want to achieve? The way they're doing this is...

On the site I sent you, the password hashing done on the user side is done once again on the server side. The purpose here is to increase security by preventing the password sent in the network traffic of anyone accessing a computer user's computer from being revealed in clear form. Since Django does not do this step, every software developer has to rack their brains, research solutions and take precautions.

glad patio
#

Correct, but then if someone has access to the 'password' (hashed password client side) via the same means they can still login to your site and undertake the same things as if they had your password...? All it is doing is changing the 'secret' used for authentication from a string of characters, to a hashed representation of that string of characters

I can see where your coming from in a password reuse sense, but I feel like thats a wider conversation then is relevant here

civic mirage
# warm ember On the site I sent you, the password hashing done on the user side is done once ...

What you're asking for is nearly impossible, definitely impractical and not an attack vector you should be thinking about (yet).

The entire web these days is built upon SSL, which utilizes asymmetric cryptographic algorithms to create certificates, which can be validated without having the private set of keys, yet stay incredibly well suited against forgery.
Now, most of that is built with RSA and elliptic curve diffie hellman for key exchanges (btw, if you're interested in cryptography, consider the diffie-hellman key exchange your entry drug :P).
If you don't believe me, log into online banking and look at the certificate.

Even with those algorithms we still require your client to have some prior certificate store which it trusts. All certificates are derived from those certificate authorities.
You are now proposing a 'zero-knowledge proof of knowledge' (sounds stupid, but that's what its called in the literature last i checked - feel free to read a bit on Wikipedia: https://en.wikipedia.org/wiki/Zero-knowledge_proof)
The issue is that passwords normally don't have the necessary complexity (either by low size, or non perfect generation by possibly a human) to be usable in most circumstances as far as i know.

There are algorithms which are suited even in those low complexity cases though (Example of so called Sigma protocols: https://cs.au.dk/~ivan/Sigma.pdf).

Now we come to the final nail in this crypto-coffin:
There exists nothing which is open source for your specific use-case
Or at the very least nothing i know about, and even if there was something, i wouldn't trust some rando implementation, neither should you!
I'm interested in cryptography, that doesn't mean i can build a secure cryptographic system, or determine the security of its implementation

#

Rolling your own crypto as its been called over the years is a dangerous game that will get you burnt if you don't have A LOT of experience.
Consider other options that ACTUALLY improve your security through means which have been thoroughly tested and are under constant scrutiny
(Examples for those are, as i've previously mentioned, multi factor authentication libraries like django-two-factor-auth: https://github.com/jazzband/django-two-factor-auth)

civic mirage
# warm ember On the site I sent you, the password hashing done on the user side is done once ...

Also, the undertone of "django not doing something like this, which it should do" is hilarious to me

The same technology allow you to log into your bank account, that let you access your medical records (if you're in a situation where those are actually digitally accessible to you)

The same tech that the military uses...

Some sites even do away with this joke by saying "Using MILITARY GRADE ENCRYPTION", yes, yes they probably are, they're just using AES...
Technically true, but not an astounding feat nowadays (i probably shouldn't say that its not an achievement, as there are still a lot of pages out there that don't support HTTPS)

#

I want to reiterate, Django's defaults are mostly sane.

That doesn't mean everything is perfect and you can just go leave it to the framework.
Django gives you the tools to build your site securely, it has pretty secure standards and there is loads of stuff out there (for quick reference a few libraries here: https://djangopackages.org/grids/g/security/) to help you make your site more secure.
It still, like any tool, needs you to make the decisions and be on the lookout.

Understanding your system's architectural security flaws, your userbase (often overlooked in my experience) and reducing attack surface by for example ensuring your dependencies are always up-to-date gets you quite far.
Security isn't a small topic, that's why we've also got a channel devoted to that topic ( #security ). Don't mindlessly fear the security systems in your application, attempt to actually understand what issues are present and attempt to mitigate those problems.
The documentation, for example, goes over the things Django already tackles in the security realm: https://docs.djangoproject.com/en/5.0/topics/security/

If you're unsure about any topic, or you get stuck, we're more than happy to help here! But you've practically ignored all my previous attempts to communicate how and why things are the way they are, thats why i've gone into a bit more detail this time, sorry for the wall of text.

warm ember
# civic mirage I want to reiterate, Django's defaults are mostly sane. **That doesn't mean eve...

Methods that hide passwords should be installed in membership login forms. It is a security problem that the password sent via post appears naked in the internet browser. If others do not take precautions, this does not mean that there is no need to take precautions. At the very least, making things difficult for the majority of people who can access the internet browser can significantly reduce any security problems that may arise.

You write a lot of things and all you say is that your password is accessible in the internet browser and it is not a problem. No! This is a problem!

#

The password must be hashed before being sent. Then it must be hashed once again and stored on the server. With each encrypted login, it must be re-hashed and decrypted to match the hashing on the server.

#

So how will we ensure this security?

civic mirage
# warm ember Methods that hide passwords should be installed in membership login forms. It is...

If somebody has access to your system, or at the very least to your browser, you have lost.

There is literally nothing you could possibly do, that would change that fact.

About hashing:
You are logically mistaken here, if you hash your password, the hashed version of your password BECOMES your secret for authentication.
It doesn't matter that its not technically your password anymore. Its hashed version poses the exact same threat.

#

What difference does it make, if your browser sends a hashed version instead of the original password?

I can use the hashed version, or the password just the same. The server doesn't know (and really can't) where i've got that secret from

Thats the entire point of the secret, to prove that i'm who i say i am

warm ember
#

Our first goal is to convert the passwords into a form that no one can understand when they see them. There are many ways for your internet browser to fall into someone's hands. And we will be taking strict action against some of these species.

civic mirage
# warm ember Our first goal is to convert the passwords into a form that no one can understan...

That isn't our first goal.

Any process or mechanism you use isn't magic. Its deterministic, it has to be, otherwise the server can't ensure that what you've sent is actually the right credential.

Also, "There are many ways for your internet browser to fall into someone's hands." doesn't make sense.
I can't stress this enough, if someone has access to your pc, either physically, or digitally in a capacity where they could get your unencrypted network traffic, or even run executables on your machine
You have lost. There is no cryptographic system on this planet that can help you.

warm ember
#

Even if the hashed password is obtained by someone, this is instant hashing. And it must also obtain and decode the information of this hashing. The security area expands with the quality of the structure to be established here. A lock cannot resist a thief. However, not every thief can bypass the locks. Having an unlocked door is worse than having it locked.

civic mirage
ornate nimbus
weary path
civic mirage
ornate nimbus
#

Ah, read some but not everything ^_^"

civic mirage
civic mirage
ornate nimbus
#

Yes, but still it might help in some cases. Just wonted to make another steer to something more practical

warm ember
#

I have a precautionary scenario in mind.

While I am typing my password, we can make additions to the password via JS. It adds 2 characters django after the first character, it adds 1 character django after the second character, it adds 4 characters django after 3 characters. As a result, the password created in the input appears to be the person's real password, but it is not. Anyone who somehow gets hold of this will fail in his attempts.

Each time a login attempt is made, Django creates another string and sends it to the server. It is decoded with the information sent to the browser and matched for the login process.

At these stages, the password is not received and hashed. While you are typing the password, Django adds something in between. It is not clear what the user wrote. At this stage, security can be increased with very clever touches.

The password sent via the post method is both hidden and the person is prohibited from adding his/her password to the input using the copy-paste method.

Currently, password rememberers in the browser are useless. Even if we tell the browser to remember the password, it will not work. 😄

civic mirage
# warm ember I have a precautionary scenario in mind. While I am typing my password, we can ...

Anything you can possibly do on the client side, has to be either coming from the user, and can be considered the login credential, or has to be sent by the server to the client

I've ignored the logical third option of generating random stuff on the client as the client would have to share that stuff in clear text with the server and it would have no value other than taking more bandwidth

Any additions you make to the password are therefore either useless, as you have to send those addtions along with the new "password", or result in a secret being sent that cannot be used for authenticating as it doesn't correspond with the hashed version on the server side

Also, you can just tell your browser to store the password and it'll push it in the input, your js will fire all the same and we've come full circle in achieving more or less nothing for the price of more complexity

warm ember
#

No matter what happens, we will be in trouble one day, so those who know the job should do something to develop a logical solution.

I'm downgrading Django from tighter security to tight security. That's how it looks in my eyes now.

civic mirage
# warm ember No matter what happens, we will be in trouble one day, so those who know the job...

You should really read up on web security and i'd recommend the django docs for a starter

You are unwilling to take solutions to problems which have been "solved" for over a decade now, using some of the best cryptography available and approaches which have been battle tested over and over

Also, just as a general concept, "some day" isn't today, not that we shouldn't worry about the future, but uncertainty isn't going to result in a successful, or secure application

warm ember
# civic mirage You should really read up on web security and i'd recommend the django docs for ...

I'm currently working on leaving Django as a junior behind. These topics are deep waters for me. While I was working with our educators, I focused on a security expert asking us to find a solution to this situation. It's not for everyone yet, but since it's a problem that concerns a narrow range of areas, I don't have to research and read much. Still, we had a very good discussion. It was very nice from my point of view. Thank you.