I have wrote a simple Django web service that provides an iOS app with JSON information containing download links.
I don't mind the JSON information to be clear text, but when the user logs in, I would like him to login with his username and password, then he would probably get some kind of key for future requests which I understand that can be sniffed out. For that first interaction, how could I protect the password and username from being clear text and sniffed?
I have decided I wanted to use a symmetric encryption to encrypt my password and have that key both on client and on server. (yes, I am aware that if someone goes to the trouble of binary hacking my app and sniffing packets from a customer he would be able to get the password in clear text, it's just not a likely concern).
I would like to use some kind of encryption that I can easily do in iOS and than decrypt in my django server. anyone has a suggestion on how to do that?
If you want to encrypt the communication between your django server and the client then you can use secure HTTP rather than plain old HTTP. This is done outside django, and is configured at the web server level. For example, if your django app is ran by a WSGI server like gunicorn or uWSGI which in return is handled by nginx (this is a common setup) then you would configure your nginx server to accept only secure HTTP requests and forward any standard http request to https. This way you can ensure that everything the client sends to the server is encrypted on the browser prior to sending. Similar setup is done with Apache, though I personally have never used Apache with django.
Since the OP feels that HTTPS is not a viable option a modification of CHAP Challenge-Handshake Authentication Protocol for the initial key creation might be an option.
Related
From the Electron renderer, I am accessing a local GraphQL endpoint served by a Django instance on my computer, which I'd like to do over HTTP, not HTTPS. But Electron's Chromium seems to intercept my fetch request and preemptively return a 307 redirect.
So if my fetch request is POST to http://local.myapp.com:3000/v1/graphql, then Chromium returns a 307 and forces a redirect to https://local.myapp.com:3000/v1/graphql, which fails because my server is listening on port 3000 and for my use case I can't do a local cert for local.myapp.com.
Theoretically the first insecure request should be hitting an nginx docker container listening on port 3000 without any SSL requirement. And nginx is proxying the request to a Hasura container. But I'm not even seeing the requests in the nginx access logs, so I'm pretty sure the request is being intercepted by Chromium.
I believe this StackOverflow comment summarizes well why this is happening: https://stackoverflow.com/a/34213531
Although I don't recall ever returning a Strict-Transport-Security header from my GraphQL endpoint or Django server.
I have tried the following code without success to turn off this Chromium behavior within my Electron app:
import { app, } from 'electron'
app.commandLine.appendSwitch('ignore-certificate-errors',)
app.commandLine.appendSwitch('allow-insecure-localhost', )
app.commandLine.appendSwitch('ignore-urlfetcher-cert-requests', )
app.commandLine.appendSwitch('allow-running-insecure-content', )
I have also tried setting the fetch options to include {redirect: 'manual'} and {redirect: 'error'}. I can prevent the redirect but that doesn't do me any good because I need to make a successful request to the endpoint to get my data.
I tried replacing the native fetch with electron-fetch (link) and cross-fetch (link) but there seems to be no change in behavior when I swap either of those out.
Edit: Also, making the request to my GraphQL outside of Electron with the exact same header and body info works fine (via Insomnia).
So I have a couple of questions:
Is there a way to programmatically view/clear the list of HSTS domains that is being used by Chromium within Electron?
Is there a better way to accomplish what I'm trying to do?
I think the issue might be from the server, most servers don't allow HTTP in any possible way, they'll drop the data transfer and redirect you to HTTPS and there's a clear reason why they would do that.
Imagine you have an app that connects through HTTPS to send your API in return for some data, if someone just changed the https:// to http:// that'd mean the data will be sent un-encrypted and no matter what you do with your API key, it'll be exposed, that's why the servers don't ever allow any HTTP request, they don't accept even a single bit of data.
I could think of two solutions.
Chromium is not the reason for the redirect, our Django instance might be configured as production or with HTTPS listeners.
Nginx might be the one who's doing the redirecting (having a little bit of SSL def on the configuration)
Last but not least, just generate a cert with OpenSSL (on host http://local.myapp.com:3000/) note: include the port and use that on your Django instance. You can trust the certificate so that it could work everywhere on your computer.
i got a little odd situation to develop.
The MVC web system my team has to develop (or project is made with rails), will rely on login/password from another site.
The idea is, the user will have a log-in on the third part site, and somewhere relevant, will exist a link to our site. When the user click on that link, we need receive from the site, some data of the user.
We have no control of the third part server, or direct access to their database. Plus, making then make any change to their application/infrastructure is a BIGDEAL so i am searching for a solution with less impact for then. (Of course they will have do change something but will be a political issue, so the less, the better)
From our viem, we need to be sure that the user really come from the third part site (and only from there), and we not have received a fake message from an attacker.
Their site have an valid SSL certificate working. (no idea if my system will have one (it should))
Not sure if its relevant, but we think that their server is an oracle aplication server, who connect to a oracle server in their internal network.
I first thought in using just SSL, but i not sure how to do it (what i have to check, what i have to change?) and if is safe enought.
My second thought is to use PGP keys, and make then sing and cryptography the data before sending to us, and, the link yo our site, would make a post to a control on our server which would verify and de-crypt the data.
Anyone have any tips/pointers/thoughts that could help me?
If both servers are using SSL, and supposing the server give you at least a json or xml interface, should be ok to simply make a secure request (using, for example, rest-client) and evaluating the response in your server.
Most likely you will want to cache user data on login in your server, and if user/password aren't found, look in the other server - this will reduce the load.
I'm trying to make a secure protocol between an iPhone app and an Arduino server. The goal is that the iPhone app makes a request to an Arduino server and the server only processes it if it has the proper credentials of one form or another. I'm not really sure how to approach this problem. Any suggestions are much appreciated!
Unfortunately there are no truly secure communication options available on Arduino. The basic problem is that SSL libraries have not been ported to this platform, partly owing to the fact that the 8-bit processors the platform is built around are not very powerful. Having said that there are some things you can do, but you'll have to do them yourself:
Basic access authentication is a very insecure method of controlling access to HTTP pages so it isn't recommended. Digest access authentication, on the other hand, employs one-way cryptographic encoding (hashing). It only requires MD5 library, which, is actually available for Arduino. What you'll need to do is modify the source code for the Web Server class to support digest access authentication: AFAIK it does not support it out of the box.
If this seems to difficult, you could implement something fairly basic (and not very secure, but better than nothing) yourself. It might look like this:
The first GET request comes in from a client
The server responds with "not authorized" response, embedding in the response a token which is related to (perhaps a hash of) the requesting IP address. You could make the original timeframe part of the hash as well, and give such tokens a limited lifetime.
If the next request from the same IP address includes a hash based on some secret code + the token sent, the next request is honored.
Now this will not protect you from IP address spoofing, and many other things I probably haven't thought of. However, it will give you a modicum of security (and a tiny bit of security through obscurity, if you believe in this sort of a thing). You could ask for (slightly) more elaborate schemes on superuser
You might be able to just use authenticated messages built on shared secrets. The message will contain [at minimum] a message type, message body, timestamp, and message digest. You create the digest by HMACing the other stuff with a shared secret. (Type HMAC Arduino into Google for libaries and code.) The message is sent over TCP or UDP (i prefer it). The Arduino computes digest of message, checks it, validates data, and then acts on message.
One thing I like to do is implement port-knocking or something at the network layer in front of the application server. This prevents unwanted traffic from reaching the custom (and possibly vulnerable) command server. This can be done stealthily (see Silent Knock) or obviously. The network protections can also be implemented by a dedicated device that does the heavily lifting and disqualifies much rogue traffic before it reaches the Arduino.
I know that there are a ton of threads about this. But I'm still confused.
I've got an app that making request to my server(nodeJS) to get JSON-data.
For the moment everyone can get everything at: http://myserver/allUpdates/ with no password. They just have to know the URL.
So I thought I would do it little more secure.
I been looking at Basic Auth, that seems to work by sending username and password in the header for every request.
Is that enough?
Some guys say that it doesn't do much if youre not using SSL. But it must be better than nothing, right?
I've never used SSL and it seems there is a lot to learn.
So my question is, should I bother with auth when I'm not using SSL?
Or are there other alternatives?
Some guys say that it doesn't do much if youre not using SSL. But it must be better than nothing, right?
Unfortunately, those guys are right. Basic Auth is, when sent plaintext, probably worse than nothing as it gives you the vague feeling of some security without any actual security.
This is because it is trivial to intercept network requests through a proxy or similar. If you're not used SSL then every parameter you're sending is easily and readily visible, including your basic authentication credentials.
In answer to your question "should I bother with auth when I'm not using SSL?" - that depends. If you want to ensure your data is only accessed by authenticated users, then it's really SSL or nothing. But if all you're trying to do is reduce the burden on your servers (i.e, rate limiting), then maybe not. I'm going to assume you're looking to do the former, in which case I'd recommend taking the time to get to grips with SSL. There are lots of resources out there about using Node with SSL, depending upon what additional frameworks you might be using (Express, etc).
SSL encrypts your requests, which means that anyone that sniffs your network traffic can't read the payload of the request.
You have two ways to auth the client to the server:
send credentials or an API key with every request OR
login in the client once with credentials or API key and reuse it's session
In both ways, you should use SSL and send the credentials with your POST data.
How can I future-proof my client URL links to my server for future HTTPS migration?
I have a .net winforms client talking to my ruby on rails backend. If I move the website in the future I want to make sure that my API links from the client don't have to change.
Or is this something a hosting provider can let you configure.
Oh, and when I do migrate I will not want any non HTTPS to occur.
PS1 - I am not talking about moving servers here, just upgrading the existing web application server with a certificate and moving to HTTPS only traffic
Place a base url as a config parameter in your client application, then run all new links through a getLinkURL(String relativeDestination) method which will give you a full url.
If you're worried about clients that haven't been updated making non-http requests, in your http (non-secure) vhost just Redirect 301 / https:// on your server.
If I understand the question correctly, I think you can solve this by using relative links everywhere; unless there's a reason you can't do that?
I think you need to look into DNS and how it works. It's not going to protect you against an HTTP to HTTPS migration but would allow you to move servers without re-engineering your code. Ideally I think you'd look to have a config setting in your code to switch from HTTP to HTTPS (and back) when necessary.