🎃

colorsなどのnpmパッケージに悪意あるコードが含まれている問題について

2022/01/10に公開

追記: 2022年1月11日 2:29 JSTにDoS脆弱性としてセキュリティアドバイザーが出されて、悪意あるバージョン(1.4.1や1.4.2)はnpmからunpublishされ、npmの最新は安全なバージョンである1.4.0へと変更されました。


2022-01-08 に colors というnpmパッケージにDoS攻撃のコードが含まれたバージョンが1.4.44-liberty-2として公開されました。

colorsの次のバージョンには、無限ループが発生するDoS攻撃のコードが含まれています。

  • 1.4.44-liberty-2
  • 1.4.1
  • 1.4.2

Semantic Versioningにより ^1.0.0 を指定している場合は、2022-01-10時点での1.x.xの最新である1.4.2が選択される危険な状態となっています。

https://semver.npmjs.com/

影響を受けるパッケージ

colorsの次のバージョンを利用している場合は、影響を受けます。

  • 1.4.44-liberty-2
  • 1.4.1
  • 1.4.2

また、colorsはターミナルに出力するログの色付けに広く利用されているため、colorsを使っているライブラリを使ってるケースやツールも影響を受ける可能性があります。

具体的にはwinston, http-server, cypress, karma, aws-cdk, promptなどが影響を受け、直接的/間接的な依存を含めると最大5万以上のパッケージがこの問題の影響を受けます。

確認方法

colorsを利用しているかは、次のコマンドで確認できます。

npmの場合

npm ls colors

yarnの場合

yarn why colors

それぞれの出力結果に、影響を受けているcolorsのバージョンがある場合は、対応が必要になります。

また、colorsへの依存があるが、バージョンが1.4.0以下のバージョンの場合は、yarn.lockpackage-lock.jsonなどのロックファイルがあるかを確認してください。
ロックファイルがない場合は、npm installなどをした際にインストールされるバージョンが変わる可能性があるため、ロックファイルまたは後述する対応が必要です。

対応方法

colorsのAuthorであるMarakのアカウントでpublishされており、またcolorsの他のAuthorはこのDoS攻撃のコードが含まれたバージョンの公開と同時にアクセス権が削除されています。

deps.devのEvent履歴

https://deps.dev/npm/colors/1.4.2/

そのため、この問題の根本的な対応ができるのは、Marak本人かnpmの管理者となります。

2022-01-10時点では、公式に修正されたcolorsの新しいバージョンはありません。~
~そのため、アップデートではなく安全なバージョンへ固定するなどといった回避策で修正が必要です。

追記(2022-01-11): 問題のあるバージョンがnpmから非公開となりました。

問題のあった 1.4.1, 1.4.2, 1.4.44-liberty-2 がnpm上で非公開となり、安全であった 1.4.0 がnpmの最新のバージョンとなるように修正されました。
そのため、緊急的な対応は不要となりました。

また、GitHubによりこの問題のセキュリティアドバイザリーが公開されています。

一時的な対応方法

colors@1.4.0は問題ないコードであることが確認されています。

また、npmでは2016年の通称leftpadという問題をきっかけに、publishしてから24時間以上経過したパッケージのunpublishは基本的にできません。
そのため、colors.jsの1.4.0の内容が基本的に変わることはありません。

そのため、この問題への一時的な対応方法としては、colors1.4.0のバージョンに固定する方法があります。

直接colorsパッケージを利用している場合は、依存するバージョンをcolors@1.4.0へ固定する必要があります。

{
  "dependencies": {
    "colors": "1.4.0"
  }
}

ライブラリがcolorsに依存(間接的な依存)している場合は、この方法では固定できません。
たとえば、アプリケーションがwinstonを使っていて、winstoncolorsへ依存しているようなケースなど。
これらの間接的な依存も、Yarnやnpmなどのパッケージマネージャの機能を利用してバージョンを固定する方法があります。

Yarnでのresolutionsを使った固定方法

Yarnにはresolutionsという間接的な依存を含めた特定のライブラリのバージョンを固定する機能があります。

package.jsonresolutionsフィールドを追加し、次のようにcolorsのバージョンを固定することでこの問題を回避できます。

{
  "resolutions": {
    "colors": "1.4.0"
  }
}

Example:

Documentations:

npm 8.3+でのoverridesを使った固定方法

npm 8.3.0overridesというYarnのresolutionsと類似する機能が実装されています。

package.jsonoverridesフィールドを追加し、次のようにcolorsのバージョンを1.4.0へ固定することでこの問題を回避できます。

{
  "overrides": {
    "colors@1": "1.4.0"
  }
}

Example:

Documentations:

npm 8.3未満での固定方法

残念ながら公式な方法はないと思います。(あったらコメントください)
package-lock.jsonを直接編集するかnpm-force-resolutions - npmなどで編集する必要があります。

その他の代替ライブラリへ移行する

@DABHによる1.4.0相当のライブラリが@dabh/colorsとして公開されています。
@DABHcolorsのメンテナーで、この問題が起きた際に誰かによってcolorsへのアクセス権限が削除されています

類似する問題

colors.jsと同様の作者(Marak)によって公開されていた、faker.jsも空の内容が6.6.6として公開され、リポジトリも空になっています

Marakがアクセス権(Owner または Maintainer)を持っているパッケージの一覧は次のとおりです。

関連する記事

関連する議論

Discussion