Hacker News new | ask | show | jobs
by alias_neo 2612 days ago
I've always wondered, how it could be that someone can be smart enough to write what on the surface is some fairly clean Golang, and yet at the same time, dumb enough to put secrets in the code.

I can forgive the use of MD5, because they probably just don't know their hashing/crypto but secrets? It's literally in the name.

There is so much material in your 5 links alone, that anyone who desires could utterly own their infrastructure, and then some.

4 comments

> dumb enough to put secrets in the code.

Man, I have tons of auth data in services like AWS just in environment variables. But pushing your rsa key to github must have happened on a bad monday.

I do often have auth info in code, plainly because of time constraints. You just have to remember it before pushing anything on github.

But aside from that, is it possible to file a DMCA for anything that has been forked if it was published under a license that permitted that action?

> You just have to remember it before pushing anything on github.

Do you read commit history looking for, say, relocated secrets? Do you go through the pain of rewriting said history regardless of whether you avoid merges with your current workflow or not? For me, that's too many risky and involving things to do. This advice will only work if you're only going to export squashed commits from private repo to the public one once in a while.

The best thing to do is assume the secret is fully compromised the second it hits GitHub, and consider it worthless to protect with these measures. Get a new secret immediately and trash the old one.
I think they examples you've listed are different, and more acceptable than pushing secrets and private keys to Github because you had dozens of them hard-coded.

As for the aside, I imagine (with no background knowledge here) that as "owner" if you accidentally published something within that licensed code that does not belong or isn't covered by that license, you should probably have the right to remove it

What if I accidentally contributed a little bit too much code to the Linux kernel? What if that code had been in the last 10 releases? What about the users and distributions running those versions?

I'm not sure the answer is, or should be, as simple as "derp - delete immediately, this was never meant to be Open Source".

That said, if the code was stolen, and then published under an OS licence - it's not OS. The "publisher" never had the rights to make it OS, so the "contract" is null and void...

This is what I was thinking. If it's something that wasn't meant to be published, I assume your right as the owner hold.

How you'd solve this, logistically in an example like yours (Linux kernel) I have no idea, but I presume by the time it's been made public long enough to be cloned/forked (a la the company in question in OP) all of your efforts should be focused on damage control.

Much of it is api keys they would distribute in the deployed app anyway. Not really ‘secret’.
That’s how it starts though. If everything is provided at deploy and nothing is ever embedded in source code there’s no way you can end up in this situation.

In some industries it’s also an audit or legal requirement that developers not have access to production credentials, so there’s no other way to reasonably handle that.

Edit: also, rebuilding your source because an API key changed... no thanks.

The choices are:

1. api key is publicly readable in a configuration files you ship

2. api key is compiled into the binary you ship.

There is only obfuscation. Then again api keys are not security keys.

But literally in this case it was security keys.

Even including an API key into the binary build is avoidable. Add an OAuth-style negotiation for the key as the first startup process.

Start digging deeper and there are fewer and fewer reasons.

> Add an OAuth-style negotiation for the key as the first startup process.

How does this possibly work? You must have some “bootstrap key” that you would use to fetch the API key. You’re going to ship something in the app that says “hey, I’m really your app” or else you’re doing to allow anyone to fetch your API key. All you can do is obfuscate the process of getting the API key. You cannot actually keep it secret when you need clients to have access to it.

Case in point: valid user credentials and it doesn’t matter what app is trying to authenticate. Issue a different key for every user (or every user per login or device) and your problem is solved.

Even if your app doesn’t require any login there’s no reason you shouldn’t go through the same process. Every device gets its own key and then you apply limits to it...

You need an api key if you show Google Maps in your app. The api key allows your app, running on the users device, to get the map tiles. Is it possible to do that without the users device having access to the key? No. Does that require user login? No. Does ‘OAuth style negotiation’ have anything to do with that? No. Is it security? No. Can you change how Google Maps works? No.
3. API key is in an environment variable configured IN the environment.

4. You use a secret service that has pk or secure access from the service machine to retrieve secure configs/settings from.

It’s one of those things that you dangerously start when your project is small then when you balloon in size, you find that everyone is hard coding secrets in code and standing up some secrets infrastructure would take weeks to get right. It’s easier now with tools like Vault but let’s say you joined bilibili today - where do you even begin? You have a massive cultural problem before you even begin to tackle the technical one. Even a smart engineer may just resign to doing things the wrong way than trying to fight a huge political battle.
>> you find that everyone is hard coding secrets in code and standing up some secrets infrastructure would take weeks to get right.

You open up the code, find all of the secrets (e.g. using high-entropy substring search), replace them with access to a global variable, and set it from a file set by a configuration from a command line.

Done.

>You open up the code, find all of the secrets (e.g. using high-entropy substring search), replace them with access to a global variable, and set it from a file set by a configuration from a command line.

Huh? Amazingly you make it sound so easy when it's anything but. Where is this file? How is it deployed? How is it rotated? If I have 10,000 VMs, how do I deliver that file to those machines? If my VMs aren't persistent, how do I ensure new VMs are deployed with this file?

Or were you thinking that they would just ssh into production and scp the file into there? To me you glossed over so many details that you hardly solved the problem at all. Replacing the secrets in source code is the _easy_ part. Deploying secrets is the hard part.

There are tools out there to make this easy, but (1) they almost always make things harder for developers and (2) they almost always require a large infrastructure change. Sure, if your deployment is small enough where you could just SSH into a single prod server and scp a file - then you are likely miles ahead - in terms of both security and culture, but changing the culture is harder than it looks.

I don't want to sound like I am making excuses for them - but I only want to show how shortcuts when you are small can snowball into a culture where you have a gaping wound that may be difficult to fix.

And when your manager says don’t do that because it’s a waste of time?
My honest answer to that is; get it in writing, because WHEN the shit hits the fan, you've got evidence in your favour.

Managers always want compromises for cost or speed, is up to us to make them understand which compromises they really don't want to make. If they want to make it anyway, get proof that it was done on their orders.

If you aren't allowed to do it right, I'm not sure what kind of advice will be useful.
Oh you're absolutely right, but there are some fairly straightforward steps to take to mitigate the risk with little effort.

You can take arguments or env vars or config files (not added to Git) for your secrets. If you begin with a system of not putting the secrets in the code, ever, it's fairly straightforward to not make this mistake.

A few minutes of setup on a repository and a mindfulness to be sure not to commit any new secret files that may be in use (and add them to the .gitignore) is a great start before getting to secret management a la Vault.

For reference, here is my getConfig which uses the environment for configuration options. It's really easy enough to start with something like this, and add it in at the baseline.

https://gist.github.com/tracker1/fcc39f40a0d14648501d329c7bd...

> dumb enough to put secrets in the code.

Even Apple has released code doing "dumb" things. goto goto for example [1]. This is a simple mistake, easily caught using proper code reviewing techniques and tools, and yet it still happened. This means they could have prevented someone making this mistake if they invested the time and energy doing things properly. This is Apple here. We aren't even talking about mistakes from Microsoft or Amazon or other major software companies.

And these people aren't dumb. Facebook isn't filled with "dumb" people, and yet, they've done far worse than Bilibili here with just their 'mistakes'.

The reality is, smart people do dumb things all the time because they are trying to get things done.

I'm not going to pass judgement on what other people did. I'm going to assume they did the best they could, and while they made mistakes, it doesn't make them dumb. Maybe someone got lazy, maybe someone was under pressure, and things just piled up.

"It's bad, but we'll get to it later when we have the time."

No one plans to have their code shared out to the public. I wonder how many of us could honestly come out clean for code they've written along the way. To not have someone say "Oh, you are using an older library there that's got a security bug" or "You shouldn't have done this" and what not.

[1]: https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-got...