9

I've created a method to allow my project EditVideoBot to be 'decentralised', where rather than the program processing and uploading all video editing requests on my own central server, users can volunteer to run this program on their computer and take some of the load off my server.

I'd like to be able to start distributing the program, but I have one major concern:

In order for the program to upload the final edited video to Twitter, it needs my Twitter API keys. Obviously, I need a way to encrypt the keys so they're not accessible to the user running the program (otherwise they have full access to my account).

The bot is programmed in Python. I don't really know where to begin with keeping the keys secure if the program is running on another computer.

Edit: If there was a method with the Twitter API to generate keys that have restricted priveliges (e.g. they can only access the media-upload endpoint but not any other endpoints) that would be the best method. (like with Cloudflare's API). Then, they'd forward the returned media-id to my server where it has full access and posts the tweet attaching the media ID. I don't think they have that capability though, so another method is needed.

3
  • 18
    I think your best bet is to expose an API in your server that different bot programs send videos to post to Twitter. – Limit Mar 23 at 4:29
  • 10
    With regard to your edit, even if Twitter allowed this, you wouldn't want to publish the keys to be able to upload arbitrary media to your account. Someone would inevitably abuse them in a way that would get your account banned. – Zach Lipton Mar 24 at 3:59
  • 4
    Rule #1: any program running on a computer, cannot hide anything from the rightful owner of that computer. Rule #2: You should not take a key issued on your name and then publish it to someone else. – inquisitive Mar 24 at 7:56
41

As specified, the problem is completely impossible. You can not, and should not attempt to, make a program - much less a script - do something its user can't see. There are many ways the attacker could break this. They could just read and analyze your python scripts (even if compiled, .pyc is easy to decompile). They could debug the program as it runs. They could intercept the network requests it makes to Twitter and pull the key out of there. They could replace the Python HTTPS library with one that wraps the official API and also logs a copy of the requests and responses to plain text. They could load your program as a library of another python program and programmatically examine its contents... Seriously, people keep asking about this and it just can not be done.

As @Limit's comment says, your best bet is to expose an API from your server, and have your script call that with whatever it wants to put on Twitter. You can then validate the message before posting it, rate-limit each client's uploads, prevent abuse of the account such as deleting tweets or using DMs, and revoke third-party access to the account entirely just by disabling the endpoint on your server. This isn't enough to totally prevent abuse, but it'll do a lot better than any method of trying to hide secrets in a Python script.

Another option is to use unique Twitter accounts per user. Either require the users to create/supply their own account (which your server then learns about and monitors for uploads, perhaps with specific tags or mentions), or automatically create one (well, as automatically as Twitter will let you get away with) for each node and don't use them for anything else (the user running the node would still have full access to the account in each case, but not to any other accounts).

Or you could just have the nodes send the resulting videos to your server, and your server decides what to do with them. This is basically the same as the first viable approach, except the new endpoint is not "send video here to upload to Twitter", it's just "send video here when done" and you-the-server-owner decide what to do with it then.

5
  • 4
    Unique Twitter accounts would probably not end up too well. I think the best option right now is to just have the video sent to my server, where it gets uploaded from so it can still maintain sole access to the account. I appreciate the detailed answer. – pigeonburger Mar 23 at 20:32
  • 1
    I get where you're coming from, but although it may be impractical, it's strictly speaking not impossible. Homomorphic encryption and Intel SGX come to mind. – Fax Mar 24 at 15:58
  • Hey CBHacking, one question, because Twitter is using HTTPS it would be impossible to intercept the network if you are using a custom HTTPS package. won't it? – Vinay Sheoran Mar 29 at 20:34
  • because for an attacker to decrypt the intercepted data, he/she needs to add/replace CA certificate for the HTTPS library, use the library that doesn't allow changing CA, or write your own. – Vinay Sheoran Mar 29 at 20:40
  • 1
    @VinaySheoran What you're describing is more commonly known as "pinning" a certificate (or public key), and there are legit reasons to do it, but it doesn't actually solve the problem here. EVEN if you manage to prevent decryption of the network traffic, the attacker can still decompile your app to find its secrets. But getting around pinning is easy. You could find the place in the app where Twitter's key is pinned, and replace it. You could replace the whole library with a different one. You could patch the library to always return true for every cert validity check. Tons of options. – CBHacking Mar 30 at 7:37
10

Obviously, I need a way to encrypt they keys so they're not accessible to the user running the program

Obviously, this is impossible.

Keys are just data. Software is just data. Everything is just data, and if the data is in someone else’s computer, you cannot prevent them from accessing the data! (It is just like writing something on a piece of paper and handing it to someone else – you cannot prevent them from reading it! The only exception is if you encrypt the data and do not give them access to the decryption key – but that will not help you here.)

The above discussion implies that you need to trust the user with the key. You cannot avoid this trust problem, but you may be able to shift it to a different target. Some hardware, such as Intel CPUs that support Software Guard Extensions, allows its owner to effectively hand control of the hardware back to the manufacturer, at least as far as the so-called “enclave” is concerned. If …

  1. you can convince the user to run your code in a supported enclave;
  2. you trust the manufacturer to keep their private key secret (which is a very big “if”, especially if the same key is used in every copy of the hardware);
  3. you use the corresponding public key to verify that the user is in fact using the enclave;
  4. you trust the manufacturer or your code to avoid side channel attacks (which is also a very big “if”, given that recent CPUs – including some designed with side channel attacks in mind – already have many known attacks); and
  5. you trust the manufacturer to make the enclave immune to any other software or hardware-based attacks (which is also a very big “if” given that the user has physical control over the hardware)

… then you shift the trust problem from the user to the manufacturer. In spite of all these caveats, some people seem to think enclaves are useful; technically, this is an answer to the question posed. But there are so many issues with it that it does not seem like a real answer.

In any case, your overall aim of creating a distributed bot that can post to your account sounds like a disaster waiting to happen. If you do not trust the volunteers to refrain from accessing your API keys, how can you trust them to, say, refrain from returning the kind of videos you do not want to be associated with? One answer is to use an enclave, with all of the caveats discussed above.

users can volunteer to run this program on their computer and take some of the load off my server

There might be an easier way of making this happen, which was hinted at in the EditVideoBot FAQ:

Where can I find the source code of the bot?

You can't, not yet at least. The main reason I haven't made it open source is because I don't know where I want to take this project in the future. I predict that I'll eventually make it open source, however.

Just do it. It is good for spreading the computing load among many computers. It is good for spreading the development effort among many developers. Most relevant to this site, it is good for security.

10
  • 1
    As long as the keys are not distributed as part of the source, of course. – GalacticCowboy Mar 23 at 19:24
  • 3
    @user253751 Nah, that doesn't work either. To use Twitter's API, the data needs to leave the enclave. (Also the enclave is only secure against people who aren't trying to get the data out.) – wizzwizz4 Mar 23 at 21:16
  • 4
    @user253751 You must have a vivid imagination. You're giving the keys to the user, on the user's computer, and expecting them to remain hidden. Who says they have to be put in the enclave in the first place? All that has to happen is for anyone to exfiltrate Intel's key. – wizzwizz4 Mar 23 at 21:29
  • 1
    +1 for the notion that you also have to trust the users to actually do the requested edit and not return something else instead. – AVee Mar 24 at 13:21
  • 1
    I added sections about enclaves in response to the comments above. But I have little knowledge of them. In particular, I wonder if the manufacturers really use the same key in each copy of the hardware. That does not seem reasonable. – Brian Drake Mar 24 at 14:49
-6

Oauth2 was made for delegating access. Twitter has extensive support and good documentation. Never share your API keys directly!

https://developer.twitter.com/en/docs/authentication/overview

This 15 min video could be helpful if you are unfamiliar with Oauth2

https://youtu.be/t18YB3xDfXI

4
  • 4
    Could you be more specific? I had a quick look through that documentation and could not see anything about the sort of delegation the OP wants. – Brian Drake Mar 23 at 12:05
  • 4
    This really needs to be fleshed out and connect some dots for how this can be used to achieve that the OP needs. – schroeder Mar 23 at 12:32
  • 2
    Unfortunately Twitter's tokens are very simple and don't allow for scoped tokens so this makes the approach useless for the asker – loa_in_ Mar 23 at 14:00
  • 3
    We should not have to follow links, especially links to 15 minute videos. Links should be accompanied by a description that adequately summarises the link and addresses the question (given that the rest of your post does not do so). – Brian Drake Mar 24 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.