PostgreSQL Db traffic encryption with Django - django

I am using Django 3.08 with a PostgreSQL 12 Remote server. I have searched the docs for Postgres and Django, but can’t find discussion of how/if Django encrypts the traffic between my app and the dB.
It looks like to me that the traffic is encrypted using md5 encryption by default in PostgreSQL based on the settings in PostgreSQL,and sends it by tcp over port 5432. It is my understanding that md5 is no longer sufficient encryption. However PostgreSQL has supported scram-Sha-256 since PostgreSQL 10. Does anyone know or have a reference to where I can set my app to use the stronger encryption or is it all taken care of if I set all traffic on my site to use https in the settings.py file. Or, will Django use scram-Sha-256 if I just change the setting in PostgreSQL?

md5 and scram-sha-256 are for password-based authentication, not for encryption. While the password exchange itself would not be readable in clear text to someone eavesdropping on the connection, the rest of the data (queries and results) still would be readable, and changeable if the session is hijacked.
Encryption is implemented by ssl (common), or in recent versions perhaps by encryption tied to GSSAPI authentication (which I think is rare).
The reference of course would be the documentation for the server and the client (Django as far as I know uses psycopg2, which in turn uses libpq)

Related

Parse server with ElastiCache redis server and password

I have set up a working Parse server on Elastic Beanstalk. I have added an AWS ElasticCache Redis server to use for caching but I can't get the connection to work when using a password, only without. In my Parse server index.js file where I create the new Parse server I connect with Redis like this:
// Redis cache server
var RedisCacheAdapter = require('parse-server').RedisCacheAdapter;
var redisurl='rediss://:'+process.env.REDIS_PASS+'#'+process.env.REDIS_URL
var redisOptions = {url: redisurl};
var redisCache = new RedisCacheAdapter(redisOptions);
Where my URL looks like REDIS_URL=clustercfg.xxxx.xxxx.use1.cache.amazonaws.com
I have tried both redis:// and rediss://. I understand that the RedisCacheAdapter takes only one option - the URL. I thought I could add in the password directly in the link but it does not seem like the adapter parses into password and URL but just expects the URL.
My question is am I doing something wrong here or is there another way to use a password? If it is not possible to use the password I wonder what the reason is (is it because ElastiCache is hidden from the internet and only seen by the server on EC2)?
Update:
Base on comments from #MarkB I tested a few different settings for ElastiCache with my code above modified to also use a password.
var redisOptions = {url: redisurl, password: process.env.REDIS_PASS};
Running ElastiCache with cluster mode, encryption at rest, encryption in transit, and Redis password fails.
Running ElastiCache with encryption at rest, encryption in transit and Redis password fails.
Running ElastiCache with encryption at rest, and encryption in transit, no password fails.
Running ElastiCache without encryption at rest, encryption in transit and no password succeeds.
Seems to me that using encryption at rest and in transit when connecting from Parse server causes a problem I am not sure how to fix. As #MarkB mentioned, the connection between Parse server (EC2) and ElastiCache is restricted to VPC so I am OK with not having the security options, but still, it would be nice.
According to the Parse Server documentation here, the redisOptions will be passed directly to the redis client documented here which supports a password field. I believe that's how you need to be specifying a password instead of specifying it in the URL.
Also note it says if you are using a Redis Client version <2.5 you need to specify auth_pass instead of password.
As you mentioned, with ElastiCache being restricted to your VPC many people consider that secure enough without adding password authentication, unless that is required for something like PCI or HIPAA compliance reasons.

Encryption/decryption of cookies by HAProxy

We're trying to set up a load balancer with HAProxy which will serve multiple backend web applications. The use case is something like this:
User browses to foo.com/app1
HAProxy sees that the cookie doesn't contain session information, and redirects to an authentication gateway (a single-sign-on page of sorts)
The auth gateway provides a form, where if the user successfully logs in, the gateway redirects back to HAProxy, with a COOKIE storing the session details
HAProxy now sees that valid session information is present and redirects to app1-internal.foo.com (the actual web application) with the same COOKIE - which is used further by the web application.
Our doubt is in the 3rd step. We would like to encrypt the cookie which the authentication gateway adds (via AES or similar). The problem is, that at the HAProxy end we can't seem to figure out how to decrypt it, since HAProxy doesn't seem to support decrypting headers (or even running an external C/C++ program that can decrypt it). So our questions are:
Can we decrypt AES encrypted headers at HAProxy itself (note that this is not an SSL connection) ?
Is HAProxy not really designed for this use case - is there a better tool for this purpose that you can suggest for us?
Many thanks in advance!

How to use HTTPS for webservice and android app?

Im working on some JSON-based web service that is supposed to work with Android application.
I would like to encrypt data transport between client (android) and server (virtual server in datacenter).
I don't have to make sure that my server is my server, just data encryption.
I have no idea how to use HTTPS.
Do I just put my PHP files in private_html and use https://example.com url?
To use HTTPS, you don't have to do anything in the coding of your web service - it's all in your hosting. Here the are steps you can follow. The specific instructions differ in your hosting (IIS, Apache, AWS/Azure, etc), but you can google specifics on how to accomplish any of these steps for whatever host and application framework you decide.
Buy an SSL certificate (there are many different vendors, but expect between $75-$200 for the certificate) based on the vendor, reputation, and level of security you need.
Generate a certificate signing request (CSR) from the server you'll be hosting.
Upload the CSR to the SSL vendor who will validate and provide the certificate for your use.
Import the SSL certificate into your application server, and configure the site to use the certificate. For instance, if you're hosting Microsoft IIS, you'd import the SSL certificate and then add HTTPS bindings on 443 to the specific website hosting your web service.
Another point of security. Since you are deploying SSL, you don't have to do any application level encryption (assuming you are not putting sensitive information in query strings - use POST if you think you need to). You probably would want to implement some security to restrict access to your web service so only your app can access it. Best practice is some level of OAuth, but at a minimum some type of pre-shared key in the header of the request is a lot better than nothing.
Here are some additional sites for more information:
https://www.digicert.com/ssl-certificate-installation.htm
https://support.godaddy.com/help/category/742/ssl-certificates-installing-ssl-certificates?prog_id=GoDaddy
If you don't want to pay for a certificate, you can use certificate signet by your own CA and add the root certificates into your application using HTTPClient and keystores
Here there's some guides
http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/
http://developer.android.com/reference/org/apache/http/client/HttpClient.html
KeyStore, HttpClient, and HTTPS: Can someone explain this code to me?
http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/
You can limit users to use JUST and only HTTPS in apache, IIS or whatever do you use. If your client connects to your server, his communications will be likely to encrypted, because he is already using HTTPS. And for responsing in HTTPS you virtually cannot send HTTPS responses, as far as I know, unless that other side isn't also a website (for example, if you have your website, you could send such a response e.g. to Google). You should be okay to send data like http status codes (OK, NotModified, PageNotFound, ...), or if you want something more, or if it is a requirement, then there you still have JSON and you could encode it as well, with some encoding algorithms, or use binary JSON format.
Check if your hosting company provides a free public shared https address. Most of them do.
If you want to understand how to do it right, follow this thread
Warning: Don't stick with the solution below for production.
If you plan o use an https endpoint without a certificate you have to make sure to disable peer verification, check this answer

encrypting form data before submitting to server

I have developed a Django application and now want to make sure the POST data transmitted through the page is safe.
I have couple of questions about this?
I see SSL certificates being displayed on many webpages. How do I get this certificate?
Do I need to change anything on my submitted form to encrypt the data or should I change any settings on my webserver?
I know its a general question but it would be great if someone provides a good answer.
First off, the POST data transmitted through the page is never safe from an application perspective. You don't have control over the user of the website. SSL and HTTPS helps prevent man in the middle attacks to ensure the request from the client (browser) to your server is encrypted. The underlying data that is sent can be malicious, so you should always validate inputs.
Secondly, if you want to use HTTPS and SSL, which I highly recommend, you'll need to obtain a certificate from one of the providers out there and install it with your webserver, which I presume is apache. Typically your domain provider can help you with obtaining an SSL certificate for your domain from one of the main certificate authorities. Regarding the installation and setup, there is tons of information about this online as it's a common task. I'm not familiar with Apache configuration to provide any specific recommendations. You'll also want to have rewrite rules so that your site can only be accessed via HTTPS and if someone tries to use HTTP, it simply redirects to HTTPS.
Lastly, you don't need to do anything in your Django application as your webserver should handle the basic interactions between your server and client to validate the HTTPS requests.

Do you know of a NGiNX module that performs something similar to verification of Amazon Web Service request signatures?

I'd like to restrict access to my web service to registered clients. The first thing I thought of was to mimic that of AWS which, in a nutshell, issues clients a non-secret and secret key pair, and requires clients to prove knowledge of the secret key by using a cryptographic function of some of the HTTP request data and the secret key, then specifying the output of the crypto function in a request header. AWS does the same and checks that the expected signature matches what the client has specified. The secret is not transmitted, blah blah. This is pretty typical and not that interesting albeit useful.
http://mws.amazon.com/docs/devGuide/Signatures.html
http://chrisroos.co.uk/blog/2009-01-31-implementing-version-2-of-the-amazon-aws-http-request-signature-in-ruby
My preferred web server for web services is nginx. I'd like to start requiring similar request signatures in certain services. It makes sense to me to create an nginx module that handles request signature validation before ever sending the request to an upstream process (my web service instance(s)).
Do you know of such a nginx module? Do you know of a different one that I can base my work off of?
There's a decent nginx module writing guide here:
http://www.evanmiller.org/nginx-modules-guide.html
Please note that I'm not asking "how do I write a nginx module?" I'm simply trying to avoid reinventing the wheel.
Thanks!
If I'm understanding correctly, you could simply check for custom headers with an if($http_{yourheader}){} and validate that against a backend such as memcached, or proxy to a fastcgi script, or even use an embedded perl script (although this will be slow and could block).
AFAIK there aren't any specific standard or third-party modules that do this, but a combination of them could provide a suitable solution (eg; $http_{header} + redis backend, for instance).
Is there a particular reason you're not looking to use custom SSL certs? They would seem an adequate solution for restricting access with added security.