And the connected web of open source.
By: Dan Lorenc
Tags: Security, Kubernetes, Go, Github

And the connected web of open source.

This isn’t another post talking about how many CVEs are in open source code (a lot), or how hard to use the CVE system is (very). It’s also not about how under-paid and overworked maintainers are (depressingly so), although it does touch on these topics. This is a post about another reason to update dependencies, one that I just realized.

Why not? It’ll only take a minute…

I was playing around with the snyk CLI to see the CVEs present in a few of my codebases. I had some spare time and wanted to see if I could fix a few. I started with Tekton, a project I help maintain. Running snyk showed a high severity vulnerability!

$ snyk test Testing /Users/dlorenc/go/src/github.com/tektoncd/pipeline… ✗ High severity vulnerability found in github.com/dgrijalva/jwt-go

I remembered hearing about this one on Twitter somehow, and decided to try fixing it just to see what it would take. I didn’t think JSON Web Tokens were used anywhere in Tekton so this probably wasn’t affecting our code, but it still couldn’t hurt to make the red x go away.

I didn’t really know where this dependency was coming from or how to get started fixing the issue. Go modules comes with a nice tool to explain your dependency tree, so I tried that out and was able to quickly track down where in my code the dependency was coming from.

$ go mod why github.com/dgrijalva/jwt-go

# github.com/dgrijalva/jwt-go github.com/tektoncd/pipeline/pkg/pod

github.com/google/go-containerregistry/pkg/authn/k8schain

github.com/vdemeester/k8s-pkg-credentialprovider/azure

github.com/Azure/go-autorest/autorest/adal

github.com/dgrijalva/jwt-go

In this case, it was an indirect dependency, so I couldn’t fix it just by updating it directly. I needed to update the things using it. I browsed over to the package repo to see what the fix was and if I could just update, and I hit one of the saddest things in open source — an abandoned project. A fix has been pending for awhile, but no one is around to merge it:

This is sad for the maintainer, this is sad for the people depending on the library — it’s sad in general. That’s another larger topic of discussion that I’ll write about some other time though. From reading the discussion on the PR/issues, it looks like there are a few forks of this, but nothing is a clear replacement yet. I saw a reference to an issue in the Azure/go-autorest repository, which was next up on my list:

I jumped up there and saw that they were able to move forward by replacing this dependency with one of the forks. Great news for me! I just need to get the updated Azure/go-autorest library into my tree. Next up is Vincent Demeester ‘s k8s-pkg-credential-provider library. I was pretty familiar with this code, so I was confident I’d be able to get a fix in if he hadn’t already. I should have known better, of course Vincent already addressed this months ago. He’s a machine!

OK, so now we’re getting up to code I maintain. Next on the list is google/go-containerregistry. I was starting to feel a little bad — I hadn’t been paying close enough attention to realize this somewhat widely used library (200+ imports), was flagged with a High Severity vulnerability. Luckily, a kind stranger on the internet (thanks Markus Thömmes!) had already taken care of that, and my co-maintainers Jason Hall and Matt Moore had merged it.

So all I had to do was apply the fix in Tekton. A quick PR (and then a couple days spent debugging and fixing newly failing tests) got me in business. At this point I was really only continuing out of some vague drive to actually fix something, even though I didn’t think the vulnerability really affected Tekton. Any other week and I might have just stopped or gotten sidetracked with something important.

Maybe this was just me coming up with a post-hoc rationalization for spending so much time fixing one probably irrelevant CVE warning, but I convinced myself this wasn’t a waste of time at all. I had just unblocked the next set of projects in the dependency graph (probably even some more I’m responsible for, sorry internet…) from updating and picking up the fix. They might even be using the dependency differently, causing that CVE to affect them!

I’m not pretending I did a huge community service here, but it did make me realize that as soon as you publish code intended for others to reuse, you become part of a larger graph of open source.

Being a responsible citizen in this web requires staying up to date and picking up changes, even if they don’t matter to your code.

I’m thrilled to see all the new automation work taking off across the open source universe to make this easier and faster. Dependabot PRs are awesome. CI services make merging these PRs easier and less risky. Faster, more frequent updates make it easier to update faster.

My colleague David Wheeler recently shared the libyear metric with me, and I really like it. Libyears reflects an almost tangible way to measure how old a dependency tree really is. The exciting part to me is that we could even try to track this over time and see the effect of things like Dependabot and other tools have on lowering the libyears across an entire language ecosystem!

Maybe the real CVE fixes were the friends we made along the way?