@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

flatmap-streamの話の整理

この記事を読んだメモ

qiita.com

対処としてはflatmap-streamに依存しているパッケージはそれを消すか更新しましょう。ということらしい。

以下のコマンドで利用しているか確認できるとのこと。

npm ls flatmap-stream

整理

  • 背景
    • copayというbitcoinのウォレットに bitcoinを盗むコード を注入しようとした。
    • 盗むコードの入ったパッケージ(flatmap-stream)を作って、copayにそれを注入することを画策
    • そのままcopayが依存するとバレる
  • 戦略
    • copayが依存するパッケージに盗むコードを追加して、マイナーバージョンアップに混ぜ込む
      • copayからすると依存するパッケージの更新なのでcopay利用者やcopay開発者には気づかれない
      • 依存パッケージのバージョン指定がマイナーバージョン、パッチバージョンの更新は受け入れるものが多い
  • 手順
    • copayが依存していて、すでにメンテされていないパッケージ (event-stream)をターゲットにする
    • event-streamのメンテナを引き継ぐ
    • event-stream (v3.x) をflatmap-stream(悪意のない状態のコード v0.1.0)に依存させる
      • ここでもパッチバージョンの更新を受け入れるようにする
    • copayが依存を更新してflatmap-stream v0.1.0に依存するのを待つ ※1のdiff
    • event-streamからflatmap-streamの依存を消してメジャーバージョンアップする(v4.x)
      • npmのサイトが表示する最新のメジャーバージョンとなり、依存するパッケージ一覧からflatmap-streamが消える
    • flatmap-streamに盗むコードを追加して v0.1.1としてリリース
    • copayが依存を更新してflatmap-stream v0.1.1が取り込まれるのを待つ ※2のdiff

copayに取り込まれたコミットのdiff

2つ。どちらも全く別の内容のコミットで、copay関係者は気づけない。

※1のdiff

github.com

@@ -7316,18 +7207,19 @@
        }
      },
      "event-stream": {
-       "version": "3.3.4",
-       "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
-       "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+       "version": "3.3.6",
+       "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz",
+       "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==",
        "dev": true,
        "requires": {
-         "duplexer": "~0.1.1",
-         "from": "~0",
-         "map-stream": "~0.1.0",
-         "pause-stream": "0.0.11",
-         "split": "0.3",
-         "stream-combiner": "~0.0.4",
-         "through": "~2.3.1"
+         "duplexer": "^0.1.1",
+         "flatmap-stream": "^0.1.0",
+         "from": "^0.1.7",
+         "map-stream": "0.0.7",
+         "pause-stream": "^0.0.11",
+         "split": "^1.0.1",
+         "stream-combiner": "^0.2.2",
+         "through": "^2.3.8"
        }
      },
      "eventemitter3": {
@@ -7858,6 +7742,12 @@
          "is-buffer": "~1.1.2"
        }
      },
+     "flatmap-stream": {
+       "version": "0.1.0",
+       "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz",
+       "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==",
+       "dev": true
+     },
      "flush-write-stream": {
        "version": "1.0.3",
        "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",

※2のdiff

github.com

@@ -7287,7 +7641,7 @@
        "dev": true,
        "requires": {
          "duplexer": "0.1.1",
-         "flatmap-stream": "0.1.0",
+         "flatmap-stream": "0.1.1",
          "from": "0.1.7",
          "map-stream": "0.0.7",
          "pause-stream": "0.0.11",
@@ -7817,9 +8095,9 @@
        }
      },
      "flatmap-stream": {
-       "version": "0.1.0",
-       "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.0.tgz",
-       "integrity": "sha512-Nlic4ZRYxikqnK5rj3YoxDVKGGtUjcNDUtvQ7XsdGLZmMwdUYnXf10o1zcXtzEZTBgc6GxeRpQxV/Wu3WPIIHA==",
+       "version": "0.1.1",
+       "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.1.tgz",
+       "integrity": "sha512-lAq4tLbm3sidmdCN8G3ExaxH7cUCtP5mgDvrYowsx84dcYkJJ4I28N7gkxA6+YlSXzaGLJYIDEi9WGfXzMiXdw==",
        "dev": true
      },
      "flush-write-stream": {