I have a need to provide an update service where client software (that I control) can request download files, but any other clients cannot download the files.
Currently using a terrible method with hashed query strings based on date, path, and a secret, which are then validated and have an expiration. Also, HTTP, so yeah it’s broken, but it at least prevents drive by scraping.
At this point we have no need for assymetric (don’t need to identify the requester, just need to prevent spoofing). What method of securing would you recommend?
1. Step one is HTTPS. Since you control the client, ideally just one ciphersuite. Maybe pinning? But given that it's HTTP now, maybe this this is running in a production environment that's hostile to good ideas? (Of course, plain HTTPS as usually configured doesn't authenticate the client.)
2. Step two is a bit more complex. I assume your clients hold the secret, know what path they want to hit, and compute the key that way?
Tell me a bit more about the clients: what are they implemented in? What do they run on? Can you reliably ship updates?
(I'd prefer to have this discussion here but if you can't discuss publicly I'd be happy to take a look. My contact info is in my HN profile.)
> But given that it's HTTP now, maybe this this is running in a production environment that's hostile to good ideas?
How did you know! ;)
I’ll probably hit you up on the side, but there are multiple clients each with their own technical debt, and it’s an old solution, but I’m putting things in place now to make changes more possible, maybe per client app using separate hostnames, for example, so that we can transition to the new without breaking the old.
I think most of the client apps actually hit a manifest API first that gives out signed urls. This already happens over https in most cases. Some may generate their own, but I’m not sure all the usage scenarios.
I can’t give more details on the clients here, but let’s just assume they are diverse and difficult but not impossible to upgrade. It’s the kind of thing we want to get right the first time and has to work for a decade.
Okiedokie. That sounds like catnip to me, so please do. Happy to sign (non-silly) mNDAs if that helps.
Probably the most useful thing for me to know is: what's the algorithm for signing a URL? If everything uses a manifest API, can you just make that a random token instead of a signature, and store that token in a database somewhere with an expiry?
Why not just use client certificates? (Not a rhetorical question. Client certificates seem like the “obvious” solution so I assume there’s a reason you’re not recommending them.)
It's a fair question, but in my experience client certs run into all manner of roadblocks in corporate or complex environments.
TLS terminating LBs/WAFs/<things> that cant authenticate the client cert or pass the public key through to something that can, dealing with key/cert expiry, nobody to run the PKI infra with any interest managing identities of things that aren't AD computers, you name it.
Yeah, my default would absolutely be client certs. That's where my question about "an environment hostile to good ideas" comes from -- I was assuming the lack of HTTPS was there for a reason.
Mmm. I really like mutual auth (TLS client certs) but one caveat:
Now somebody needs to manage the resulting PKI.
Even what looks like the no effort case, where you punt to the Web PKI and have all the clients use Web PKI certs (ie client1.example.com needs a cert with SAN dnsName client1.example.com like a web server would have but making sure the EKU for client auth is asserted) means now you have to either keep pace with us, or risk an impedance mismatch if our policies change in a way you're not OK with.
If you use one or more private CAs there's a tension between on the one hand the convenience of it not being your problem, and on the other hand the risk that it turns out you were just engaged in theatre and there's, for example, an unsecured SCEP server that will happily give any adversary with network access an authorised certificate with whatever identity they ask for...
Simpler: just let everyone download an encrypted version of the files. Then only allow your client software that you control to decrypt the downloaded files.
Encrypt the files using AES-GCM. If you trust that your own client software is distributed securely and won't run in hostile environments and be reverse engineered, just ship that AES key with your software. Otherwise it will get complicated fast.
Currently using a terrible method with hashed query strings based on date, path, and a secret, which are then validated and have an expiration. Also, HTTP, so yeah it’s broken, but it at least prevents drive by scraping.
At this point we have no need for assymetric (don’t need to identify the requester, just need to prevent spoofing). What method of securing would you recommend?