Jack022
Jack022

Reputation: 1257

How can i store sensitive data in a Django project?

I'm building a project where i will be able to save an API key, then this key will be used to perform some operations on my site from an external python bot.

Obviously, no one should access the key, except my code that will perform some tasks using those keys.

At the actual moment, the keys are stored on my database and they are not encrypted, but now i would like to make this system as safe as possible, so that even if someone has access to my credentials, he can't use it.

The problem is that i know very little about security and encription. My first thought was to encrypt the keys, but i don't really know how to do that.

Basically, that's how it should work: the keys are submitted using a form -> the keys must be encrypted and saved on my db -> later on, when i need to perform a task, those keys should be decrypted in order to do what i need

Is my approach correct? And how can i accomplish that in Django?

Here is my current view:

def homepage(request):
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = ApiForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            send = form.save()
            send.save()
            messages.success(request, f"Success")

    else:
        form = ApiForm()

    return render(request,
                  "main/home.html",
                  context={"form":form})

And here is the form:

class ApiForm(forms.ModelForm):

    key = forms.CharField(widget=forms.TextInput(
        attrs={
            'placeholder': 'Enter here your api key',
            }
        ), #max_length=9
    )

    secret = forms.CharField(widget=forms.TextInput(
        attrs={
            'placeholder': 'Enter here your secret key',
            }
        ), 
    )


    class Meta:
        model = MyModel
        fields = ("key", "secret")

    def save(self, commit=True):
        send = super(ApiForm, self).save(commit=False)
        if commit:
            send.save()
        return send

Keep in mind that those API keys will be used by an external Python scrypt that will perform some operations, so they need to be decrypted by that script.

Upvotes: 1

Views: 3557

Answers (1)

Tomasz Zieliński
Tomasz Zieliński

Reputation: 16356

Here's how I would approach the problem (but please note that depending on your specific circumstances/requirements/etc. it might be either an overkill or a completely irresponsible approach! I'm just thinking out loud here.).

If you encrypt the API keys in the database using symmetric encryption, then any attacker that manages to compromise the web server will have access to the encryption keys (because the app has access to them) and so would be able to decrypt the API keys. Still, it would protect you if e.g. the database backups were leaked, but not the encryption key. (I'm assuming here that the encryption is performed correctly which, as life shows, is a separate issue!)

A likely better solution (but harder to implement correctly) would be to use asymmetric encryption and then separate the web server from the worker script.

Specifically, the web server can encrypt the API keys using a public key and store them in the database. Then, the worker script running under a different user (or better, on a separate machine) can decrypt them using a private key that is neither known to nor accessible by the web server.

This solution protects you against database leaks and web server compromises (well, sort of, it's not trivial to set all the required things correctly and even then vulnerabilities like Heartbleed occasionally pop up...).

Still, the worker script needs to use the API keys decrypted so it's your weak point no matter how secure the other parts of the system are.

There are also dedicated solutions for secret management like Vault, but even if you use them and correctly secure the whole setup, the worker script will remain your weak point.

Upvotes: 6

Related Questions