- PVSM.RU - https://www.pvsm.ru -

Веская причина для проверки ваших зависимостей: AGPL-edition

Вот вы берёте код под лицензиями BSD, MIT и Apache2 и в ус не дуете, а потом – бац! – вторая смена, и в транзитивной зависимости рисуется код под AGPL. Мы стараемся следить за этим и предпочитаем скорее перебдеть, чем недобдеть.

Веская причина для проверки ваших зависимостей: AGPL-edition - 1

Прежде чем добавить в любой из своих проектов новые зависимости, я всегда делаю базовую проверку. Что я проверяю (стандартный чеклист):

  • Под какой лицензией выпущен код?
  • Кто автор?
  • Есть ли какие-то серьёзные нерешённые проблемы в трекере ошибок?
  • Ведётся ли история серьёзных багов в трекере ошибок?
  • Каким образом происходит код-ревью для пулреквестов?

После этого я бегло просматриваю сам код в поисках чего-то явно небезопасного или вредоносного. Это нужно, чтобы почувствовать качество самой кодовой базы. Далее я пытаюсь найти «коричневые M&Ms» [1] – незначительные детали, которые могут указывать на большие проблемы. И рекурсивно повторяю всё вышесказанное с транзитивными зависимостями. Кроме того, я ещё раз бегло просматриваю код каждый раз, когда обновляю зависимость.

Это довольно большой объём работы, но она необходима, чтобы не стать жертвой атак типа event-stream [2]. А недавно мне напомнили ещё об одной веской причине для проверки зависимостей. В тот момент я делал ревью активно рекламируемой библиотеки [3] от Duo для WebAuthn на Go, она лежит тут: github.com/duo-labs/webauthn [4].

Всё началось с того, что я заметил несколько «коричневых M&M's»:

  • Данные логировались в stdout, несмотря на то, что это библиотека.
  • Код был с запашком.

Конечно же, эти мелкие проблемы были лишь предвестниками чего-то большего: когда я начал ревью одной из транзитивных зависимостей (github.com/katzenpost/core/crypto/eddsa [5]), меня встретил заголовок лицензии AGPLv3 [6].

Это плохая новость для тех, кто хочет использовать библиотеку WebAuthn от Duo. Несмотря на то, что Duo лицензировал свою библиотеку под BSD, выбирая её, вы также связываете своё приложение с библиотекой AGPL. А, по мнению (A)GPL, таким образом вы создаёте «модифицированный» продукт, попадающий под правила раздела 13 AGPL [7]:

Если вы вносите изменения в программу, ваша изменённая версия должна явно предлагать всем пользователям, взаимодействующим с ней удалённо через сеть (если ваша версия поддерживает такое взаимодействие), возможность получить бесплатный свободный доступ к исходному коду вашей версии с помощью стандартных средств копирования программного обеспечения (несмотря на любые другие положения настоящей Лицензии).

Другими словами, если вы использовали github.com/duo-labs/webauthn [8] в общедоступном web-приложении, теперь ваше web-приложение должно быть с открытым исходным кодом.

Самая возмутительная вещь об этой зависимости заключается в том, что она дублирует golang.org/x/crypto/ed25519 [9] – одну из квазистандартных «х» библиотек [10] Go.

По факту github.com/duo-labs/webauthn [8] – это то же самое, что и первоначально используемая golang.org/x/crypto/ed25519 [11]. Подмена произошли во время пулреквеста внешней коллаборации под названием «Consolidate COSE things to their own area» [12]. В процессе переноса части кода из одного файла в другой этот пулреквест незаметно изменил реализацию OKPPublicKeyData.Verify.

Вот OKPPublicKeyData.Verify, который использует golang.org/x/crypto/ed25519 [11]:

// 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
}

А вот OKPPublicKeyData.Verify, который использует AGPL-лицензированный github.com/katzenpost/core/crypto/eddsa [5]:

// 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
}

Этому изменению не было дано никакого объяснения. Ревью пулреквеста провели два сотрудника [13] Duo, одобрили его и смержили.

Именно поэтому мне не нравится принимать запросы на пулреквесты, которые перемещают код. Даже если новая организация кода лучше прежнего, затраченное время на проверку «не делает ли новый пулреквест чего-нибудь лишнего» съедает слишком много времени.

Я разместил предупреждение [14] о зависимости библиотеки с лицензией AGPL, и разработчики вернули обратно [15] golang.org/x/crypto/ed25519 [11]. Несмотря на это, я решил не использовать github.com/duo-labs/webauthn [8]. Основная часть библиотеки и её зависимостей предназначена для поддержки WebAuthn misfeature под названием attestation, которую у меня есть меньше, чем нулевое желание использовать. Я только что закончил писать значительно более простую, свободную от attestation библиотеку, и по размеру она меньше, чем одна десятая от вышеупомянутой. Скоро я открою её исходный код. Разработка этой библиотеки вышла дешевле, чем ответственность за использование существующей WebAuthn Go библиотеки.

Этот случай напомнил мне, почему мне нравится программирование на Go. Благодаря обширным стандартным и квазистандартным «х» библиотекам Go, в моих проектах обычно мало дополнительных зависимостей. А хорошая репутация и операционные процедуры Go позволяют мне не париться и не заниматься перепроверкой исходного кода компилятора и стандартных библиотек. И, несмотря на то, что я люблю Rust, я прихожу в ужас каждый раз, когда смотрю на дерево зависимостей их типичных библиотек: обычно я вижу десятки транзитивных зависимостей, написанных непонятными рандомными чуваками из интернета, которым у меня нет никаких оснований доверять. Проверка всех этих зависимостей занимает слишком много времени, поэтому я гораздо менее продуктивен в Rust, чем Go.

Последнее замечание: как поклонник проверяемых структур данных, таких как Прозрачность сертификатов (Certificate Transparency), я должен любить новую базу данных Go checksum database [16]. Однако checksum database не принесёт вам никакой пользы, если вы не потратите время на проверку своих зависимостей. К сожалению, я уже видел одного чрезмерно увлечённого пользователя Go, утверждающего, что checksum database решает все проблемы с управлением зависимостями. Но это не так. Нет никаких простых способов, чтобы от этого избавиться, и вам нужно смириться с фактом: время от времени нужно делать ревью зависимостей в ваших проектах.

Автор: zverolyub

Источник [17]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/344262

Ссылки в тексте:

[1] «коричневые M&Ms»: https://www.entrepreneur.com/article/232420

[2] event-stream: https://blog.npmjs.org/post/180565383195/details-about-the-event-stream-incident

[3] активно рекламируемой библиотеки: https://webauthn.io

[4] github.com/duo-labs/webauthn: https://github.com/duo-labs/webauthn

[5] github.com/katzenpost/core/crypto/eddsa: http://github.com/katzenpost/core/crypto/eddsa

[6] лицензии AGPLv3: https://github.com/katzenpost/core/blob/d5cf686c5a7811418262be381d27b43c1fea2e6c/crypto/eddsa/eddsa.go#L1-L15

[7] раздела 13 AGPL: https://www.gnu.org/licenses/agpl-3.0.en.html#section13

[8] github.com/duo-labs/webauthn: http://github.com/duo-labs/webauthn

[9] golang.org/x/crypto/ed25519: https://godoc.org/golang.org/x/crypto/ed25519

[10] квазистандартных «х» библиотек: https://github.com/golang/go/wiki/SubRepositories

[11] golang.org/x/crypto/ed25519: http://golang.org/x/crypto/ed25519

[12] «Consolidate COSE things to their own area»: https://github.com/duo-labs/webauthn/pull/25

[13] два сотрудника: https://github.com/duo-labs/webauthn/pull/25#issuecomment-472051532

[14] разместил предупреждение: https://github.com/duo-labs/webauthn/issues/56

[15] вернули обратно: https://github.com/duo-labs/webauthn/pull/58

[16] Go checksum database: https://go.googlesource.com/proposal/+/master/design/25530-sumdb.md

[17] Источник: https://habr.com/ru/post/484898/?utm_campaign=484898&utm_source=habrahabr&utm_medium=rss