I know that Django websites contain a secret key which is not to be disclosed to anyone. However, I really want to showcase my website on GitHub, as I feel it is nice. Unfortunately, I am worried about the secret key's security, and if it would be safe to upload that website to GitHub where everyone can see.
The website type is a personal portfolio website that showcases my projects and more.
So, would it be okay to upload my entire Django Project to GitHub? The only sensitive information I can think of would be my superuser information, and maybe my database, where I store all my project Models for displaying on the website. Pretty much all I know I need to guard is my superuser information
The django secret key should not be publicly available (see https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SECRET_KEY)
Many sites use an environment variable to set the key.
So your settings file could have something like:
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', '')
Have a look at https://github.com/jpadilla/django-dotenv.
You can set your secret_key inside a .env file which you should add to your .gitignore. This means it will not be tracked or added to any git commit, hence, won't be shown in Github.
Related
I'm new to Django just started learning it today, since I am quite proficient in express/nodejs and mongodb, I know there are some variables that one should not push to github as they can contain passwords and other identifying information. On express/node I create a .env file and add it to my .gitignore, typically containing the password to my mongodb connection.
I am about to push my first Django api project to github and want to know if there are any other information besides the "SECRET_KEY" that I should protect. Also is .env file still the best way to protect it in Django. Furthermore I have my Django project within a ll_env-virtual environment should it make a difference.
Besides SECRET_KEY there are some other variables like:
Database credentials (PASSWORD, etc)
If hosted on any cloud providers, their secret keys (AWS_SECRET_KEY)
If using Email service, there will be your mail specific password and etc.
In short every variables that you think are to be secured should be stored in a .env file.
Also for the ease of development and production you can store Debug variable.
Basically .env file contains the individual user environment variables when collaborative working. This article by djangocentral may help you know more.
I new at Django and created an e-commerce website just for portfolio purpose(I will not use it for sell anything real, at most i going to host it in some domain to show as a portfolio) and committed it in a public Github repository, then Github sent me an email telling me i committed the secret keys of Django, is there any problem with this? Do i need to delete the repository and generate another Secret Key?
It should be sufficient to make sure that the committed key is not used in production by exchanging the deployed key. You don't need to delete the whole repository if you want to delete a single file and remove it from the version history. You can use this guide here to do so: https://docs.github.com/en/github/authenticating-to-github/removing-sensitive-data-from-a-repository
Following some best practices (e.g., https://12factor.net/) you should not have the secret key directly inside your settings.py but rather use an environment variable for this.
I am providing sensitive username and password file to the authenticated user. I want user to download the file via file_url in template through model.
File_link = models.FileField(upload_to='SAFE_DIRECTORY_PATH')
I don't feel it safe storing it in media directory
Any suggestions keeping them safe ,web app will be generating the link.
Some security notes first.
This is probably a bad idea. Storing sensitive information in plain files is probably not the correct security approach, especially if you plan to use Django's media storage backend for doing that. It leaves all files out-in-the-open.
If however you really, really, and I mean really need to do that, you should encrypt the file first before saving in Django.
Again though, if at all possible I would recommend to store sensitive information in db. In your case of storing passwords, you can use Django techniques to store that information relatively-safely such as correctly hashing passwords via pbkdf function (e.g. pbkdf or bcrypt, etc). If users will need to download that information, you can always generate the file on the fly for them for download.
Some suggestions for uploading files.
I usually assign random filenames to the uploaded files. This way at least its more challenging for the users to guess the filenames to download them. Not very security since this relies on security by obfuscation but its better then nothing. If you need a Django field which does that automatically, you can do that by making upload_to a callable (there are also 3rd party libs for doing that such as django-auxilium although for full disclosure Im the author of that lib).
Now that files are stored with random filenames, you probably never want to provide direct download links to the users for download but instead authenticate them first and then use something like X-Accel in nginx or X-Sendfile in Apache to actually serve the file to the user. The idea being that you first authenticate user in Django. Then however instead of Django serving the file, you return a special header which nginx/apache catches which contains a filepath to the file nginx/apache should serve to the user. This way you dont have to waste resources in Django to serve the file however you still get the advantage of being able to authenticate the request. There are a number of 3rd party apps for doing that as well.
Finally to protect users from downloading the media files you can use nginx (and I imagine apache) by restricting certain parts of the media folder:
location /media/protected {
internal;
alias /var/www/files;
}
In this case nginx will refuse direct user requests to /media/protected and will only allow to serve those files via X-Accel-Redirect header sent by Django. Then all you have to configure in Django is to store files in that path to make them protected:
models.FileField(upload_to='protected/myfiles')
I was looking for a solution to serve files only to authorized users and came across this post. I think it it is top google result for "django storing and providing secure files"
As the answer is rather old I wanted to share my finding:
django-private-storage (https://pypi.org/project/django-private-storage/) seems to be a good solution to this problem.
I am working with django, and I would like to use django-admin to manage certain things of my site, including the mantainance of the database.
Can I use it once the project is deployed or should I consider other options? I have searched for options but I didnt find anything. Leaving the admin site like www.mysite.com/admin I dont think is an option because of security issues.
Thanks
The django admin is exactly what you should be using to administrate (hence the name) your site after deployment. What are the security issues behind www.mysite.com/admin? You need a user account with staff privileges to access the admin area.
I have a django application that uses a postgres DB.
I have a chef recipe that sets up the postgres DB, including setting up a postgres username/password for the django app to use.
This username/password is then used by the DATABASES settings.py value.
At the moment I have to have the postgres details in both attributes.rb and in settings.py.
How can I have them in just one place?
Options I have currently considered:
Having settings.py (or part of it) generated by a chef template. That way the details only need to be in the chef recipe.
The downside of this is that the django app is incomplete unless it is deployed via chef. (This might not be that much of an issue, as even local dev is done with vagrant+chef).
Having a known file on the filesystem that settings.py checks and loads some values from. This file is generated by chef.
This is only a little bit better than the first solution. Also it requires some boilerplate code in settings.py to load and parse the file.
Have the details in settings.py and let chef extract them (somehow).
This approach is problematic because it muddles with the ordering in the chef recipe (I have to check out my django app, extract the value, use the values to set up postgres, and then start django).
That itself might not be too bad, but the real issue comes when/if I want to move to a system where passwords aren't in source-controlled files but in something like chef's data-bags.
I've googled quite a bit, but other than various discussions on the layout of settings.py and general talk about how to use django and chef, I can't find a nice solution.
Surely someone else has deployed a django app with postgres using chef and come across this before?
You should use a data bag. And as you store a password there, it should be encrypted data bag. Then you can read data from it in both recipes (postgres and python).
And storing your passwords in attributes also is not a good idea - because they are too exposed.