
GitHub shouldn't allow username reuse - donatj
https://donatstudios.com/GithubsTotalSecurityFacepalm
======
dasil003
Title is a little bit hyperbolic. I get that it's a real issue that needs
fixing, but a GitHub URL is not a secure package identifier, it was never
designed this way, and it's an unfortunate hack that it's become a defacto
standard.

What we really need is for language-level package managers to support signed
immutable packages, and for that to start being taken seriously above the OS-
level.

 _Edit: author changed the title, it used to say something about a "GitHub's
security facepalm"_

~~~
t0mk
I thought the same with the exaggerating. The author of the article can hardly
blame github. But he makes a good point, I never realized how much I rely on
github username policy in Go code :).

If golang allows to import from Git URLs over HTTP or SSH, then it is the same
problem with DNS as with the github usernames, isn't it? If the domain name,
from which you import, will disappear, then someone else can register it and
serve malicious code. This is also pretty hyperbolic.

IMO It's simply solvable by refering to a commit hash, like govendor does it
(or the gemfile in ruby for that matter). I am actually not sure why it's not
possible to add commit hash to a golang import, I thought that $GOPATH/src
contains only git repos (but I'm not sure about this).

~~~
strkek
Call me paranoid, but I've always assumed urls are not permanent. Domains can
change, usernames can change, and published things can be taken down.

For example, I may publish something as an online backup or a mirror of my
real repositories, without any kind of guarantee whatsoever. ONLY sharing
because I want people to be able to see how the things I do were made. I mean,
even most FOSS licenses explicitly state that there are no guarantees of any
kind.

IMHO I think people should stop with the "if it's on internet, it must retain
compatibility" mindset, and instead switch to a "this will break or disappear
at any time unless explicitly stated otherwise" mindset.

~~~
autotune
Hence why it's important to have your own software package repository server
and grab internal packages from that rather an external party for any serious
infrastructure.

------
niftich
This situation arises solely from Go's myriad dependency management tools [1],
including the latest "official experiment" 'go dep', not having the notion of
a package repository. Instead, package identity is tightly bound to package
location [2], and doing "package management" on this identity results in HTTP
GETs or equivalents to that location. This is documented as a core convention
[2] of the Go world, by the designers themselves.

I was always bewildered by this choice [3][4], because many, many other
package management systems have independently realized this to be a bad idea
-- and that it's valuable to have an extra layer of indirection between
package identity and package location to prevent this exact situation. The
component that solves this indirection is called a package repository, which
can then institute strict rules about immutability, deletions, and naming, if
so desired. NPM didn't, for a long time, until they got burned. GitHub is not
a package repository, but due to the Go community's guidance, is effectively
being used as such in a large volume of Go code in the wild.

[1]
[https://github.com/golang/go/wiki/PackageManagementTools](https://github.com/golang/go/wiki/PackageManagementTools)
[2]
[https://golang.org/doc/articles/go_command.html#tmp_1](https://golang.org/doc/articles/go_command.html#tmp_1)
[3]
[https://news.ycombinator.com/item?id=12189356](https://news.ycombinator.com/item?id=12189356)
[4]
[https://news.ycombinator.com/item?id=15677338](https://news.ycombinator.com/item?id=15677338)

~~~
cdoxsey
You can override the location of a package with dep.

Indirection doesn't solve the problem it just moves it to the centralized
repository.

Go designers recommend vendoring packages which solves the problem.

~~~
niftich
> _" You can override the location of a package with dep."_

As far as I know, this is true [1], and can be done with the 'source' rule in
Gopkg.toml. However, the guidance for dep says [1]:

 _" A source rule can specify an alternate location from which the name'd
project should be retrieved. It is primarily useful for temporarily specifying
a fork for a repository. source rules are generally brittle and should only be
used when there is no other recourse. Using them to try to circumvent network
reachability issues is typically an antipattern."_

This doesn't sound like a glowing endorsement of this feature.

> _" Indirection doesn't solve the problem it just moves it to the centralized
> repository."_

Precisely; we're in agreement. A repository can then choose to institute
sensible rules, if they so desire: Maven Central has what I would consider to
be sensible rules, while NPM prior to 'left-pad' did not. Without a
repository, the community has no place to make this decision point, so
everyone's left to fend for themselves.

> _" Go designers recommend vendoring packages which solves the problem."_

Can you point me to guidance from Go designers which substantiates your point?
I have been searching for this and have been unable to find it.

[1]
[https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md](https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md)

~~~
cdoxsey
From the faq:
[https://golang.org/doc/faq#get_version](https://golang.org/doc/faq#get_version)

> If you're using an externally supplied package and worry that it might
> change in unexpected ways, the simplest solution is to copy it to your local
> repository. (This is the approach Google takes internally.) Store the copy
> under a new import path that identifies it as a local copy. For example, you
> might copy "original.com/pkg" to "you.com/external/original.com/pkg". The
> gomvpkg program is one tool to help automate this process.

~~~
Shoothe
I think Google doesn't see the problem because they have internally _all_
their dependencies copied locally. There is no fetching of external sources so
for them the problem that some dependency URL is broken simply does not exist.

------
ecshafer
This is insane. Not that the username was reused, but rather that people are
using a direct link to GitHub as their dependency management. At minimum you
should manually fork it into a repo you control, but a proper package manager
is what is really necessary.

Would you statically link to an ftp server in your code build process? What
about to a random website for a piece of code? No, you wouldn't, and this is
equally unprofessional.

~~~
donatj
A package manager would be just as vulnerable, as mentioned in the post.

Just with a delay until you run update.

~~~
kibwen
A package manager would be vulnerable (to package hijacking via reclaimed
Github username) only if that package manager is a transparent proxy to
Github. Any package manager with its own central package repo, like NPM and
RubyGems, would be unaffected by a reclaimed Github username. Even a package
repo like crates.io, which uses Github to authenticate, wouldn't be vulnerable
because user equivalence is by user ID rather than username.

~~~
krapp
As far as I know (and correct me if I'm wrong) but NPM only manages a database
of package names, most of which link to Github repos themselves. And NPM at
least until recently allowed name reuse.

~~~
kibwen
NPM requires one to log in to NPM before pushing new versions of a package, to
which control of a specific Github username has no bearing. And I know of no
way to "link" an NPM library to a Github repo, publishing requires a local
copy and an explicit action: [https://docs.npmjs.com/getting-
started/publishing-npm-packag...](https://docs.npmjs.com/getting-
started/publishing-npm-packages)

And yes, NPM allowed name reuse, and that was bad, but that was a problem on
NPM's side, not Github's side, because NPM is supposed to be a robust package
repository and Github was just designed to be a lightweight social network for
programmers.

------
tjpd
Isn’t this the developer’s or Go’s security issue first before it’s a GH
facepalm? GH doesn’t make any representations about the provenance or the
safety of the code on their site. It is the user and toolchain that’s making
those potentially dangerous assumption, no? Doesn’t blocking id reuse open
them up to a kind of ID squatting and DOS?

~~~
edem
That's the exact reason that they _do_ have a name squatting policy:
[https://help.github.com/articles/name-squatting-
policy/](https://help.github.com/articles/name-squatting-policy/)

I am definitely _against_ this nonsense. Don't depend on some third party for
your solutions who never said that their urls are here to stay. Quite the
contrary!

~~~
mcphage
Huh. Someone once offered to buy my github username from me... I had no idea
that was explicitly against their policy. (Not that I said yes, or had any
interest in selling)

~~~
edem
But if you wish to use a name GitHub will mediate between you and the owner.
Never worked for me but it can happen.

------
ixtli
Many people appear to be accusing the author of being hyperbolic, saying
"well, you shouldn't be relying on github urls being real." This is true, but
it misses the point: whether they should have or not, people ARE using the
technology in this way. GitHub can either take an ideological stand and
continue allowing people to be unknowingly exposed to an attack surface, or
they can make a reasonable effort to defend against malicious usage of their
service. Perhaps there are material reasons why it would be wrong or
prohibitively difficult for them to change their username policy, but if it
isn't, I don't think it's unreasonable to request this of them while
simultaneously admonishing people who assuming data from github will always be
accurate.

Put another way, I would _also_ upvote an article that said "The Go package
manager is insecure because it assumes github URLs never change owners."

~~~
edem
The malicious use here is treating GitHub as a package repository. GitHub
_should not_ do anything about this other than explicitly stating that GitHub
_is not_ a package repository and they _cannot be held accountable_ for using
GitHub in a _really dumb_ way.

~~~
ishanjain28
+9000 Votes to you edem.

~~~
edem
Then it will be ... _over nine thousand_!

------
kenhwang
Or maybe Github shouldn't be used as a package repository if security is a
concern.

~~~
sergiotapia
I also think it's weird how Go uses Github HEAD as the package download
source. Strange.

~~~
shurcooL
Go doesn’t “do” that.

Using GitHub HEAD is one of many ways it can be used. It’s not a very popular
approach. People with important projects that often use other ways, such as
vendoring via a tool like dep.

~~~
calcifer
> Go doesn't "do" that

Literally the first example of the Go tour [1] tells you to run "go get".
"dep" is not (yet) an official part of Go's tooling. So when the only official
tool fetches HEAD and calls it a day, I think it's perfectly fine to say "Go
does that".

[1] [https://golang.org/doc/](https://golang.org/doc/)

~~~
slrz
The 'go get' tool is just a small convenience wrapper around git/hg/svn. Its
intended for use by developers, for quickly taking a look at some source code.
The tour use case you cited is also a good fit for 'go get'.

It was never intended to be a part of your production build process. If you
push its outputs directly to production, you're holding it wrong.

------
edem
Don't blame GitHub for Go's clearly broken dependency solutions. What
everybody should have learned after so many incidents like this is this: _an
artifact should only be deletable by nuclear fire_

GitHub has a name squatting policy for a reason. I have multiple "names"
because some guy's repo who abandoned GitHub years ago was released and I was
able to reuse it for my own brand.

This is like saying if I buy a domain it should be mine for eternity even if
it is no longer useful for me.

More about the squatting policy here: [https://help.github.com/articles/name-
squatting-policy/](https://help.github.com/articles/name-squatting-policy/)

------
sanderjd
This seems akin to a new server receiving an existing IP address. If I ssh to
that IP address after the change, it tells me the server's fingerprint has
changed and I have to make an explicit choice to trust the new server. It
seems like this could be made to work similarly.

~~~
Shoothe
And this explicit choice is not some Y/N decision that can be easily
overlooked but it's editing known hosts, so that the user understands the
seriousness.

------
mehrdadn
This reasoning is wrong to me. I see this very much as a problem with using
usernames to refer to repositories in the first place, not with username
reuse. For heaven's sake, let me just refer to a repo by a unique ID of its
own. There's no reason for the username to be in the repository URL.

~~~
TheRealPomax
So, a sha1 commit hash, which gives you an exact filesystem snapshot, and
can't be faked with identical content if someone gets their hands on someone's
account?

The real issue is Go just pointing to "whatever is the current HEAD" which is
insane.

~~~
mehrdadn
No, a commit hash points to a commit. This is for when we want to point to a
repo, i.e. For exactly the same situations where we currently use URLs with
usernames.

~~~
TheRealPomax
The original problem was Go rather stupidlt pointing to a repo, instead of a
specific commit on a repo. Normal github use at the very least would be to
point to tags. Someone deleted their account, all those tags (which are empty
commits) become invalid.

Because you're not building a list of just username and repo names for
software dependent purposes, right? That would be a massive security failing
on your part.

------
halayli
The security facepalm is the fact that you're pulling source code without
signature verification. It's not github's responsibility to manage usernames.
The blame and responsibility is on Go and whoever thought it's a good idea to
pull in code this way.

There are so many scenarios were you can end up cloning malicious code when
you're simply relying on cloning alone. What if someone hacked the author's
github account and committed malicious code? And why do you trust that the
author has no plans in the future to inject malicious code?

~~~
ashelmire
Did you just say it's not github's responsibility to manage usernames on their
own site? You're aware that attacks on similar names (not even exact ones) are
a very common form of security attack, right?

What signature verification would one have when accessing a public repo? If I
tell somebody there's a really great tool at fakename/faketool, they are
screwed.

~~~
craftyguy
> What signature verification would one have when accessing a public repo?

You can gpg sign your git commits. This is not a new feature...

~~~
Zamicol
No, don't do that. Git's gpg signing function signs the commit hash, which is
SHA1.

Until git uses something other than SHA1, this is insecure.

[https://arstechnica.com/information-technology/2017/02/at-
de...](https://arstechnica.com/information-technology/2017/02/at-deaths-door-
for-years-widely-used-sha1-function-is-now-dead/)

You can gpg sign code, but do not sign a SHA1 hash.

~~~
craftyguy
So the alternative is... do nothing?

I understand the "omg sha1" frenzy, but 1) you still need an incredible amount
of compute power to generate a collision (you read your linked article,
right?) and 2) even if you make something that collides, it still has to
compile into the project.

Perhaps nation states can do this today. If that's your concern then, well,
you've already lost because they've likely found other ways to compromise you
with much less effort. For everyone else, sha1 for commits is still not _that_
bad.

~~~
Zamicol
>"incredible amount of compute power to generate a collision"

That article sets the "best case", not the worse, and that article is "old".
The GPU/ASIC industry is bananas, and we have no idea what other breaks there
are. MD5 is a great example of how quickly these things become dangerous.

SHA1 was a terrible choice when git was made, it's a horrific one now. SHA1
cannot be used for anything security sensitive. That domain is always larger
than what we may first suspect.

>the alternative is... do nothing?

No, the alternative is to use gpg with a secure hash over and above anything
git provides. This is a bad choice because there is no standardized git
infrastructure built around anything secure.

This fragments the industry (like Go building their own, again) where git
could instead continue to unify, making an interface that has a lot of
eyeballs, visibility, and a secure, universal implementation. Instead,
fragmentation remains the solution. Git could have easily taken care of this
by simply listening to people back in ~2005 saying, "gee, maybe we shouldn't
use a hash that's already on its deathbed".
[https://www.schneier.com/blog/archives/2005/02/cryptanalysis...](https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html)

It would be nice just have used SHA-256. I hope Snowden didn't show us
nothing.

------
clhodapp
In short: "My toolchain chose to do a thing that is insecure given your
(publicly-known) approach to managing your usernames. Now I am exposed to a
security vulnerability and it's your fault!"

No! This is the go ecosystem's fault! It was knowable that GitHub managed
usernames this way and yet they still chose to introduce this security risk.

------
Everlag
(Context: I'm here late into the conversation and after the title was changed)

When you consider github.com/foo/bar you see that foo has established a
reputation by developing code for third party use. Can foo break upstream
builds that rely on HEAD? Absolutely. However, given that foo has a reputation
for high quality content is it likely for them, barring an exceptional event,
to insert malicious code? Probably not.

The issue I have with github allowing username reuse in a broader context is
that the reputation from a trusted user is transferred to a third party. That
third party could be neutral, well meaning, or malicious. All the same, they
should not be able to take the reputation developed by that user. In this
example, if foo decides to become a bespoke tailor and deletes their github,
someone should not be able to use their reputation.

In the context of go using urls as canonical locations for code, is it smelly?
Oh yeah. Does that mean that username reuse isn't a problem? No. A lot of
people here are pointing at either go developers or github. You can blame both
and eventually get a robust solution from both.

------
eclipticplane
When I did a large organization rename (GitHub helped us reclaim a name from a
long-since disused account), we were extremely cautious because of this exact
problem. Our GitHub organization was named XYZ, being renamed to ABC. We had
GitHub rename a separate user, DEF, to ABC. We then picked a low risk time and
had browser windows open when we initiated the swap of our new shiny ABC to
ABC-old to immediately grab the name and then immediately grab the old name on
a new account.

~~~
netsharc
So... they allow account takeovers without any grace periods? Amazing.

~~~
compsciphd
uh, did you read what the OP wrote? he said a long since disused account. i.e.
how long a grace period do you desire they have?

github's general policy is that if an account has been dormant for a year
(which might mean not just means commits, but also fetches from it) its can be
recycled. This is because they dont want to enable username squatting.

~~~
rileymat2
How does this work with third party login? For instance I can use my github
accout to log in to gitlab. Seems like a security risk for even dormant
accounts.

~~~
knownothing
I'd imagine all OAuth tokens associated with an account are rolled when it's
transferred.

~~~
rileymat2
I was not clear, github works as an identity provider. I am not talking about
api access to github, I am talking about using github to log into other
services.

------
3pt14159
They should only be reused if manually requested. Sometimes usernames had
nothing on them (thus a manual enable is ok) and freeing up the username after
a couple years of seeing no traffic seems fine too.

But really I kinda shudder to think of how much stuff is hackable just by
stealing the right laptop and phone while someone is on vacation.

~~~
dgacmu
There should be a way to verify that the repo you're depending on has
activated strong 2FA and opted in to a minimum waiting period for name reuse.

------
drinchev
This reminds me about the whole `left-pad` fiasco and npm allowing same-name
packages to be re-published. For a while I thought that the packages were
hijacked [1].

GitHub should definitely not allow username reuse, but most prominently it's a
Go issue, where they use GitHub as a package manager.

1 : [http://www.drinchev.com/blog/alert-npm-modules-
hijacked/](http://www.drinchev.com/blog/alert-npm-modules-hijacked/)

------
ocdtrekkie
Had a conversation in 2015 with someone who was... a bit of an irritant.
Future people tagging him in like 2017... ended up dragging in a completely
innocent bystander. Because the guy in question had changed his account name,
someone else has registered his old one, and GitHub, cluelessly, attached all
of his comments to the new user.

------
ljm
The more I read about some issues with Go, the more I realise that it's
beautiful and elegant because of the ties with Plan9 and the uncomplicated
thinking that comes with it, but it suffers greatly because it won't consider
how the world has changed since. So you get a very particular way of doing
things (`GOPATH`, `gofmt`) and you're kind of out of luck when the abstraction
leaks (`interface {}`).

Point in case: treat GitHub as part of the filesystem, so you don't need to
host a package manager. I suspect that the end game is the opposite of Java
(com.example/package/whatever) and in the long run you're expected to publish
your source to a domain you control. Starting with GitHub and services like
gopkg.in just gets people acquainted with the idea but in the enterprise
you'll be importing `enterprise.com/factory/builder` or some such.

------
smnscu
The article raises a good point, but I just wanted to take the time to praise
GitHub's support, who've been repeatedly super helpful in helping me get
inactive handles (including my own @andreis). It's definitely a far cry from
other services like Twitter.

------
q3k
Another reason to always vendor [1] your dependencies...

[1] - [https://github.com/golang/dep](https://github.com/golang/dep)

~~~
donatj
Even then, if you ever update your dependencies the problem could strike.

------
jlg23
Where does it concern GitHub's security model? This is a serious question, I
am not a GitHub user myself.

The only thing I get from the article is "people treat URLs as eternal, even
if the site does not provide strong guarantees for that."

But that is not news and moot to debate, as a site's policy can change anytime
and then you are still screwed. And nothing of this is specific to GitHub.

------
di
Hmm, it seems the same issue exists with domain names, we should probably
prevent them from being reused as well. /s

------
AdmiralAsshat
There's a similar problem in the Kodi world where a popular repo was
deactivated then re-registered by another party:

[https://torrentfreak.com/metalkettle-after-github-
takeover-1...](https://torrentfreak.com/metalkettle-after-github-
takeover-170915/)

------
EtDybNuvCu
Using nixpkgs, this isn't a problem because the source hashes will mismatch if
somebody tries to spoof a username with a malicious repository. We should all
be using Nix more often.

------
buserror
I'm glad they allow reuse. I signed up very early on github, but my username
was already taken... By someone who didn't contribute anything at all to
anything, ever; and probably never used the account again.

One day, after many years, I emailed the github guys to know if I possibly get
it, and they immediately, and very kindly agreed and renamed me.

------
s_chaudhary
I like the way gitlab approaches this. On gitlab if you change your username,
the old username can't be used by anyone again.

I have faced this problem with github. I changed my username. The very next
day, someone created an account with my old username and now all my resume,
old profiles etc. were pointing to an empty github account. :(

------
rocky1138
Why are packages from Github not given a unique hash as opposed to being tied
to a username in the URL?

------
tonyztan
It is important to note that domain names can also be reused, and a lot of
trust is assigned to certain domain names, too.

------
hnruss
Another facepalm in the comments section:

> What did GitHub say when you reported it per
> [https://help.github.com/articles/github-
> security/](https://help.github.com/articles/github-security/) ? ...

> I did not report it. ...

~~~
mehrdadn
This is not exactly an obscure scenario. If I was a better I would bet >10:1
odds they had already thought through this scenario and dismissed it for
whatever reason (maybe equating it with having an irresponsible or malicious
package author), i.e. reporting it wouldn't have done anything.

~~~
hnruss
True, but we don't know for sure. If we're making guesses, I'd guess that
someone made the decision about username re-use years ago-- before package
management systems began relying on GitHub directly. If that is the case, then
this issue could not have even been considered.

