Good reason to test your dependencies: AGPL-edition

Here you take the code under the BSD, MIT and Apache2 licenses and don’t blow the whisk, and then – bam! – the second shift, and in transitive dependence the code under AGPL is drawn. We try to keep an eye on this and prefer to overtake rather than under-finish.


Before adding new dependencies to any of my projects, I always do a basic check. What I check (standard checklist):

  • Under what license is the code issued?
  • Who is the author?
  • Are there any serious unresolved issues in the error tracker?
  • Is there a history of serious bugs in the error tracker?
  • How does a code review for pull-quests occur?

After that, I skim through the code itself in search of something obviously unsafe or malicious. This is necessary to feel the quality of the code base itself. Next, I try to find “Brown M & Ms” – minor details that may indicate big problems. And recursively repeat all of the above with transitive dependencies. In addition, I once again skim through the code every time I update the dependency.

This is a fairly large amount of work, but it is necessary so as not to become a victim of attacks like event-stream. And recently, I was reminded of another good reason for checking dependencies. At that moment I was doing a review actively advertised library from Duo for WebAuthn on Go, it lies here: github.com/duo-labs/webauthn.

It all started with the fact that I noticed a few “brown M & M’s”:

  • The data was logged in stdout, despite the fact that this is a library.
  • The code was stockpiled.

Of course, these minor issues were only the harbingers of something more: when I started a review of one of the transitive dependencies (github.com/katzenpost/core/crypto/eddsa), the headline met me AGPLv3 licenses.

This is bad news for anyone who wants to use Duo’s WebAuthn library. Despite the fact that Duo licensed its library under BSD, selecting it, you also link your application with the AGPL library. And, according to (A) the GPL, this way you create a “modified” product that falls under the rules Section 13 AGPL:

If you make changes to the program, your modified version should explicitly offer all users interacting with it remotely via the network (if your version supports this interaction) the opportunity to get free free access to the source code of your version using standard software copying tools (despite to any other provisions of this License).

In other words, if you used github.com/duo-labs/webauthn in a public web application, your web application should now be open source.

The most outrageous thing about this addiction is that it duplicates golang.org/x/crypto/ed25519 – one of quasi-standard “x” libraries Go

In fact github.com/duo-labs/webauthn Is the same as originally used golang.org/x/crypto/ed25519. The substitution occurred during a pull-quest of an external collaboration called “Consolidate COSE things to their own area”. In the process of transferring part of the code from one file to another, this pull-request imperceptibly changed the implementation OKPPublicKeyData.Verify.

Here OKPPublicKeyData.Verifywhich uses golang.org/x/crypto/ed25519:

// Verify Octet Key Pair (OKP) Public Key Signature
func (k *OKPPublicKeyData) Verify(data []byte, sig []byte) (bool, error) {
	f := HasherFromCOSEAlg(COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm))
	h := f()
	h.Write(data)
	return ed25519.Verify(k.XCoord, h.Sum(nil), sig), nil
}

But OKPPublicKeyData.Verifythat uses AGPL-licensed github.com/katzenpost/core/crypto/eddsa:

// Verify Octet Key Pair (OKP) Public Key Signature
func (k *OKPPublicKeyData) Verify(data []byte, sig []byte) (bool, error) {
	f := HasherFromCOSEAlg(COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm))
	h := f()
	h.Write(data)
	var oKey eddsa.PublicKey
	err := oKey.FromBytes(k.XCoord)
	if err != nil {
		return false, err
	}
	return oKey.Verify(h.Sum(nil), sig), nil
}

No explanation was given to this change. Pulrequest review conducted two employees Duo, approved of him and held him back.

That’s why I don’t like to accept requests for pull requests that move the code. Even if the new organization of the code is better than the previous one, the time taken to check “does the new pull-quest do something extra” eats up too much time.

I posted a warning library dependencies with AGPL license, and developers returned back golang.org/x/crypto/ed25519. Despite this, I decided not to use github.com/duo-labs/webauthn. The bulk of the library and its dependencies are designed to support WebAuthn misfeature called attestation, which I have less than zero desire to use. I just finished writing a much simpler, attestation-free library, and it is smaller than one tenth of the above. Soon I will open its source code. The development of this library came out cheaper than the responsibility for using the existing WebAuthn Go library.

This case reminded me why I like programming on Go. Thanks to Go’s extensive standard and quasi-standard “x” libraries, there are usually few additional dependencies in my projects. A good reputation and operating procedures of Go allow me not to take a steam bath and not to double-check the source code of the compiler and standard libraries. And, despite the fact that I love Rust, I am horrified every time I look at the dependency tree of their typical libraries: usually I see dozens of transitive dependencies written by obscure random dudes from the Internet that I have no reason to trust. Checking all of these dependencies takes too much time, so I’m much less productive in Rust than Go.

One final note: as a fan of verifiable data structures such as Certificate Transparency, I have to love the new database Go checksum database. However, the checksum database will not do you any good if you do not spend time checking your dependencies. Unfortunately, I have already seen one overly enthusiastic Go user claiming that the checksum database solves all the problems with dependency management. But this is not so. There are no easy ways to get rid of this, and you need to come to terms with the fact: from time to time you need to do dependency reviews in your projects.

Similar Posts

Leave a Reply