Django Secret Key Compromised - python

I am wondering what are the steps one would need to take should the production secret key become compromised. Luckily, that is not the case, but it would be good to know, nonetheless.
In particular, what happens if one simply swaps the old key to a newly generated one? Since it is used in making hashes, does it break the entire system or make it unstable?
In the case of a compromise, would the response be as simple as generating a new key and inserting it into the production settings?

The SECRET_KEY is used for the following:
All sessions if you are using any other session backend than django.contrib.sessions.backends.cache, or are using the default get_session_auth_hash().
All messages if you are using CookieStorage or FallbackStorage.
All PasswordResetView tokens.
Any usage of cryptographic signing, unless a different key is provided.
"If you rotate your secret key, all of the above will be invalidated. Secret keys are not used for passwords of users and key rotation will not affect them."
You can use the following function to generate a new key:
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
Simply copy/paste the printed results into your settings.py.

Related

i have accidently delete my sceret key form settings.py in django

while pulling from git hub i lost my secret key which i have updated. is there any way to obtain secret key for the same project.
while pulling from git hub i lost my secret key which i have updated. is there any way to obtain secret key for the same project.
run : python manage.py shell
write and enter the following lines sequentially:
from django.core.management.utils import get_random_secret_key
print(get_random_secret_key())
exit()
copy this secret_key to your settings.py SECRET_KEY. And reload this server. If it will not work, refresh the page with ctrl+shift+r, delete cache.
If it will not work again, try to remove all rows from django_session table where in your database.
My English skills are not good, sorry about that.
I don't think there is a way to restore a secret key unless you remember a place where you stored it. But I don't think that's critical that you lost it, just set a new one. It should mostly affect the existing users' sessions, i.e. currently logged in users will be signed-out and will have to sign in again.
See what SECRET_KEY is used for here
Secret keys are not used for passwords of users and key rotation will not affect them.

Implementation of RSA on google app engine webapp

This is an assignment.
I have to create a web application on the google app engine and apply the rsa algorithm for storing data on the app engine datastore. My application just stores small notes created by the user. I have finished the application and also applied RSA for encrypting the messages (got code from Implementing RSA algorithm). For that I split the string and convert each character to an ascii and then store them in a repeated ndb.IntegerProperty but I don't understand how the private and public keys are supposed to be handled. I want to know where do I store the private key and once the notes have been encrypted and the user accesses them again how do I get the public and private key? Am I supposed to store they keys in the datastore as well?
The encryption is done at the server to encrypt the notes that the user saves. The notes are strings which are broken into characters and their ascii values are then encrypted. All of this is done at the server side once the user clicks "add note".
The decryption is done at the server side when the user logs in and his user id is used to fetch the notes he has stored which are decrypted to get the original ascii values and then form the original string.
Currently there is only one key pair which is generated in the code.
link to the application : http://cloudassignment-1102.appspot.com
Let me know if I need to add the source code as well.
Ideally you store the private key somewhere (very) safe. Since GAE is the platform of your choice you have a couple of options:
Put the key somewhere in your project where it is readable by the source code, but not publicly available (In Java this is usually a resources folder or WEB-INF, not sure what the equivalent for python is)
Use cloud storage and put your file there. It's a bit of overhead but if you ever want to change the key open-heart-surgery style...
Since a key is basically just an array of bytes you could define them as a constant byte array in your source. This would obviously be the least flexible choice.
EDIT:
Let me just say that this is a stupid assignment. It makes no sense at all to use asymmetric encryption if you hide all the encryption on your server. Since your data is always decrypted before it is sent to the user this is basically the same as symmetric encryption or no encryption at all.
But in the spirit of doing stupid things and learning while at it:
I assume your code generates the key pairs for each user. Therefore it is not possible to store the keys as constants in your code (GAE filesystem is readonly). Rather you can use any kind of database you wish (be it cloud datastore or cloud sql).
Since you should have a user database entity somewhere you can put the public key in there with the rest of the user information. You can serve the public key from the database through a cloud endpoint should you require it. Since it's not a secret you don't have to protect this endpoint.
The secret key could go in the same storage (datastore / cloud sql?) but i'd separate it so you cannot query for it and hand it out by accident. An additional table / entity with a reference to a user should suffice.

Getting or deleting cache entries in Flask with the key starting with (or containing) a substring

I'm trying to delete all entries in the cache store that contain (in this case start with) a substring of the cache key, but I don't see any easy way of doing this. I'm using Memcache as backend.
If I understand the code correctly, I need to pass the full cache key when calling delete or delete_many. Is there any other way of doing this?
I'll explain what I'm trying to do in case there is a better way: I need to clear the cache for certain users when they modify their settings. Clearing the cache with clear() will remove the cache entries for all the users, which are some 110K, so I don't want to use that.
I am generating key_prefix with the ID of the user, the request's path, and other variables. The cache keys always start with the ID of the authenticated user. So ideally I would use something like delete_many(user_id + ".*")
It's not supported because Memcache is designed to be a distributed hash. There's no index of keys stored to search in.
Ideally you should know what suffixes a key may have.
If not, you could maintain an index yourself in a special key for the user.
Like user_id + '_keys' which contains a list of keys.
This way you can cycle key by key and delete all the cache for the user.
You can override the .set function to manage this new key.

A good way to encrypt database fields?

I've been asked to encrypt various db fields within the db.
Problem is that these fields need be decrypted after being read.
I'm using Django and SQL Server 2005.
Any good ideas?
See: Using Symmetric Encryption in a SQL Server 2005 Database
Yeah. Tell whoever told you to get real. Makes no / little sense. If it is about the stored values - enterprise edition 2008 can store encrypted DB files.
Otherwise, if you really need to (with all disadvantages) just encrypt them and store them as byte fields.
I had the same problem, and created the following solution: http://djangosnippets.org/snippets/2489/
I happened to use M2Crypto as the cipher engine, but that can be swapped out if desired.
As TomTom notes, doing this just raises the bar for an attacker rather than making hostile decryption impossible - in addition to accessing your database, they now also need to access wherever you store the passphrase that feeds into the key derivation function. However, by splitting the key from the data it is protecting in this way, you at least now have the option to further secure that key (e.g. with a key management server) to raise the bar yet higher. Defence in depth is a good strategy, but you also need to decide what constitutues overkill for a given application.
It's also a terrible idea to encrypt any field that might be useful for searching or sorting purposes (I only use this trick to store OAuth credentials for a web service that doesn't support proper tokenised OAuth connections).
If you are storing things like passwords, you can do this:
store users' passwords as their SHA256 hashes
get the user's password
hash it
List item
check it against the stored password
You can create a SHA-256 hash in Python by using the hashlib module.
Hope this helps

Generating unique and opaque user IDs in Google App Engine

I'm working on an application that lets registered users create or upload content, and allows anonymous users to view that content and browse registered users' pages to find that content - this is very similar to how a site like Flickr, for example, allows people to browse its users' pages.
To do this, I need a way to identify the user in the anonymous HTTP GET request. A user should be able to type http://myapplication.com/browse/<userid>/<contentid> and get to the right page - should be unique, but mustn't be something like the user's email address, for privacy reasons.
Through Google App Engine, I can get the email address associated with the user, but like I said, I don't want to use that. I can have users of my application pick a unique user name when they register, but I would like to make that optional if at all possible, so that the registration process is as short as possible.
Another option is to generate some random cookie (a GUID?) during the registration process, and use that, I don't see an obvious way of guaranteeing uniqueness of such a cookie without a trip to the database.
Is there a way, given an App Engine user object, of getting a unique identifier for that object that can be used in this way?
I'm looking for a Python solution - I forgot that GAE also supports Java now. Still, I expect the techniques to be similar, regardless of the language.
Your timing is impeccable: Just yesterday, a new release of the SDK came out, with support for unique, permanent user IDs. They meet all the criteria you specified.
I think you should distinguish between two types of users:
1) users that have logged in via Google Accounts or that have already registered on your site with a non-google e-mail address
2) users that opened your site for the first time and are not logged in in any way
For the second case, I can see no other way than to generate some random string (e.g. via uuid.uuid4() or from this user's session cookie key), as an anonymous user does not carry any unique information with himself.
For users that are logged in, however, you already have a unique identifier -- their e-mail address. I agree with your privacy concerns -- you shouldn't use it as an identifier. Instead, how about generating a string that seems random, but is in fact generated from the e-mail address? Hashing functions are perfect for this purpose. Example:
>>> import hashlib
>>> email = 'user#host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'
>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7
As hashlib.sha1 is not a random function, but for given data returns always the same result, but it is proven to be practically irreversible, you can safely present the hashed key on the website without compromising user's e-mail address. Also, you can safely assume that no two hashes of distinct e-mails will be the same (they can be, but probability of it happening is very, very small). For more information on hashing functions, consult the Wikipedia entry.
Do you mean session cookies?
Try http://code.google.com/p/gaeutilities/
What DzinX said. The only way to create an opaque key that can be authenticated without a database roundtrip is using encryption or a cryptographic hash.
Give the user a random number and hash it or encrypt it with a private key. You still run the (tiny) risk of collisions, but you can avoid this by touching the database on key creation, changing the random number in case of a collision. Make sure the random number is cryptographic, and add a long server-side random number to prevent chosen plaintext attacks.
You'll end up with a token like the Google Docs key, basically a signature proving the user is authenticated, which can be verified without touching the database.
However, given the pricing of GAE and the speed of bigtable, you're probably better off using a session ID if you really can't use Google's own authentication.

Categories