tag:crieit.net,2005:https://crieit.net/tags/colors.js/feed 「colors.js」の記事 - Crieit Crieitでタグ「colors.js」に投稿された最近の記事 2022-01-11T23:52:59+09:00 https://crieit.net/tags/colors.js/feed tag:crieit.net,2005:PublicArticle/17931 2022-01-11T23:52:59+09:00 2022-01-11T23:52:59+09:00 https://crieit.net/posts/checker-of-colors-fakers-etc-packages-20220111 colors.js, faker.js 等を使用しているか調べる簡易チェッカー <p>先日ショッキングな commit が push されたというニュースを知りました。そこで念のため colors や faker の開発者が開発したパッケージを自分のプロジェクトが使用しているかを調べる簡易チェッカーを作ってみました。</p> <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.bleepingcomputer.com/news/security/dev-corrupts-npm-libs-colors-and-faker-breaking-thousands-of-apps/">Dev corrupts NPM libs 'colors' and 'faker' breaking thousands of apps</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/azu/articles/d56615b2e11ad1">colorsなどのnpmパッケージに悪意あるコードが含まれている問題について</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://twitter.com/jingbay/status/1480458265452740609">高梨陣平さんはTwitterを使っています 「開発者 Marak Squiresは自身のOSSを故意にサボタージュ版をリリース。問題の製品は“faker.js” と “colors.js”。両者共に“LIBERTY LIBERTY LIBERTY.”の3行で始まる無意味な文字列を無限に表示。両者は週250万DL、2240万DLで影響はでかい。NPMはrevertを行いSquiresはGitHubからアクセスを奪われた。Ve」 \/ Twitter</a> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://twitter.com/jingbay/status/1480458906300477441">高梨陣平さんはTwitterを使っています 「rgeはGitHubにコメントを求めたが返答はない。その後、Bleeping Computerが2020年11月にSquiresによるもう無料で仕事はしたくないとのGitHubへの投稿を発見している。Squiresの大胆な行動はOSS開発のモラルと経済的な問題に注目を集めている。」 \/ Twitter</a></li> </ul></li> <li><a target="_blank" rel="nofollow noopener" href="https://note.com/takahiroyte/n/nd6cceae3af04">OSSのゆく道:Faker.jsの顛末|Takahiro Ito|note</a></li> </ul> <p>やろうと思えばできてしまうのがオープンソース界隈のエコシステムの怖いところではあります。</p> <p>詳細は上述の記事をご参照ください。</p> <p>それよりも、目下気になるのは自分のプロジェクトでこれらの npmパッケージ を使用していないかどうか。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://gist.githubusercontent.com/azu/11b105a9e35dc9d5f07312c24a35c82b/raw/000a0c728ac1748b6fb3c80c8a0753fb1f6a57e8/marak-packages.md">https://gist.githubusercontent.com/azu/11b105a9e35dc9d5f07312c24a35c82b/raw/000a0c728ac1748b6fb3c80c8a0753fb1f6a57e8/marak-packages.md</a></li> </ul> <p>colors や faker を開発した方がメンテナーになっているパッケージ一覧を<a target="_blank" rel="nofollow noopener" href="https://gist.github.com/azu/">azu</a>氏が作ってくださったので、このリストを元にパッケージの使用を確認する簡易チェッカーを作ってみました。</p> <h2 id="成果物"><a href="#%E6%88%90%E6%9E%9C%E7%89%A9">成果物</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/test-adramelek">GitHub - arm-band\/test-adramelek</a></li> </ul> <h2 id="コード (要点のみ)"><a href="#%E3%82%B3%E3%83%BC%E3%83%89+%28%E8%A6%81%E7%82%B9%E3%81%AE%E3%81%BF%29">コード (要点のみ)</a></h2> <pre><code class="js">const path = require('path'); const request = require('request'); const { spawnSync } = require('child_process'); const fs = require('fs'); const marakOwnedUrl = 'https://gist.githubusercontent.com/azu/11b105a9e35dc9d5f07312c24a35c82b/raw/000a0c728ac1748b6fb3c80c8a0753fb1f6a57e8/marak-packages.md'; // 略 request.get({ url: marakOwnedUrl, }, function (error, response, body) { const mdStream = body.split("\n"); const packageNamesArray = mdStream.filter((val) => { return val.length > 0 && !val.startsWith('http'); }); let cnt = { found: 0, notfound: 0, } let resultStr = `Project: ${projectPathStr} `; for (let i = 0; i < packageNamesArray.length; i++) { console.log(`yarn why ${packageNamesArray[i]}`); resultStr += `Package "${packageNamesArray[i]}": ${i + 1} / ${packageNamesArray.length} > yarn why ${packageNamesArray[i]} `; console.log(`package "${packageNamesArray[i]}": ${i + 1} / ${packageNamesArray.length}`); const spawn = spawnSync(`yarn why ${packageNamesArray[i]} --cwd ${projectPathStr}`, { shell: true }); console.log(spawn.stdout.toString()); resultStr += `${spawn.stdout.toString()} `; console.log(spawn.stderr.toString()); resultStr += `${spawn.stderr.toString()} `; spawn.stderr.toString().length > 0 ? cnt.notfound++ : cnt.found++; } const cntMsg = ` Found packages: ${cnt.found} Not found packages: ${cnt.notfound}`; console.log(cntMsg); resultStr += cntMsg; try{ fs.writeFileSync(path.join(path.join('.', 'dist'), `scan-result-${projectName}.log`), resultStr); } catch(e){ console.log(e.message); } }); </code></pre> <ul> <li>先程の mdファイル をHTTPリクエストで取得し、パッケージ名の行のみ(1行の文字列が0(改行のみ)と<code>http</code>始まりを除外)処理します</li> <li>パッケージ名分ループして、 <code>child_process</code> の <code>spawn</code> を使用し、 <code>yarn why {パッケージ名} --cwd {プロジェクトのパス}</code> コマンドを実行 (<code>npm</code> は今回は見ていません) <ul> <li>コマンドライン引数でプロジェクトのパスを指定することで、該当プロジェクトのディレクトリで <code>yarn why</code> をしています</li> </ul></li> <li>実行結果を <code>console.log</code> で表示しつつ、メモリに格納。全ての確認が終わるとテキストファイルにダンプします <ul> <li>標準出力エラー(パッケージが見付からなかった)と成功(パッケージが見付かった)をカウントして出力に付与しています</li> <li>標準出力エラーを使うために <code>spawn</code> を使用</li> </ul></li> </ul> <p>スピード重視でざっくり作りました。ひとまず自分の手元で動いて予期する動作になったので公開しました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="きっかけ"><a href="#%E3%81%8D%E3%81%A3%E3%81%8B%E3%81%91">きっかけ</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.bleepingcomputer.com/news/security/dev-corrupts-npm-libs-colors-and-faker-breaking-thousands-of-apps/">Dev corrupts NPM libs 'colors' and 'faker' breaking thousands of apps</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/azu/articles/d56615b2e11ad1">colorsなどのnpmパッケージに悪意あるコードが含まれている問題について</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://twitter.com/jingbay/status/1480458265452740609">高梨陣平さんはTwitterを使っています 「開発者 Marak Squiresは自身のOSSを故意にサボタージュ版をリリース。問題の製品は“faker.js” と “colors.js”。両者共に“LIBERTY LIBERTY LIBERTY.”の3行で始まる無意味な文字列を無限に表示。両者は週250万DL、2240万DLで影響はでかい。NPMはrevertを行いSquiresはGitHubからアクセスを奪われた。Ve」 \/ Twitter</a> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://twitter.com/jingbay/status/1480458906300477441">高梨陣平さんはTwitterを使っています 「rgeはGitHubにコメントを求めたが返答はない。その後、Bleeping Computerが2020年11月にSquiresによるもう無料で仕事はしたくないとのGitHubへの投稿を発見している。Squiresの大胆な行動はOSS開発のモラルと経済的な問題に注目を集めている。」 \/ Twitter</a></li> </ul></li> <li><a target="_blank" rel="nofollow noopener" href="https://softantenna.com/blog/developer-corrupts-his-own-widely-used-library/">オープンソース開発者が広く使用されている自分のライブラリを改ざん、大量のプロジェクトに影響 | ソフトアンテナ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/ginpei/items/a4eb012827f5a102ff4d">Firebase CLIとかの出力が2022-01-10の一時期に乱れてた件 - Qiita</a></li> </ul> <h4 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://note.com/takahiroyte/n/nd6cceae3af04">OSSのゆく道:Faker.jsの顛末|Takahiro Ito|note</a></li> </ul> <h4 id="前兆"><a href="#%E5%89%8D%E5%85%86">前兆</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://ledsun.hatenablog.com/entry/2022/01/09/090825">color.js の謎のissue - @ledsun blog</a></li> </ul> <h3 id="パッケージ一覧"><a href="#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E4%B8%80%E8%A6%A7">パッケージ一覧</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://gist.githubusercontent.com/azu/11b105a9e35dc9d5f07312c24a35c82b/raw/000a0c728ac1748b6fb3c80c8a0753fb1f6a57e8/marak-packages.md">https://gist.githubusercontent.com/azu/11b105a9e35dc9d5f07312c24a35c82b/raw/000a0c728ac1748b6fb3c80c8a0753fb1f6a57e8/marak-packages.md</a></li> </ul> <h3 id="HTTPクライアント"><a href="#HTTP%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88">HTTPクライアント</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://garafu.blogspot.com/2017/05/node-http-httpss-request.html">Node.js で HTTP\/HTTPS リクエスト を行う方法 - galife</a></li> </ul> <h3 id="コマンド実行"><a href="#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C">コマンド実行</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.wakuwakubank.com/posts/728-nodejs-child-process/">Node.js|シェルコマンドを実行する方法(child_process) - わくわくBank</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://ja.stackoverflow.com/questions/28527/node-js-%E3%81%AE-execsync-%E3%81%AE%E6%88%BB%E3%82%8A%E5%80%A4%E3%81%A7-stderr-%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B%E6%96%B9%E6%B3%95">node.js の execSync の戻り値で stderr を受け取る方法 - スタック・オーバーフロー</a> <ul> <li><code>stderr</code> を使用するならば <code>spawn</code> の方が良い</li> </ul></li> <li><a target="_blank" rel="nofollow noopener" href="https://neos21.net/blog/2019/10/18-01.html#child_processspawnsync">Node.js の Child Process 研究 : fork・exec・execFile・spawn の違いをサンプルコードとともに検証 - Neo's World</a></li> </ul> <h3 id="path"><a href="#path">path</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/oblivion/items/e9677ef4ca38643aaa14">nodejsのpathモジュールの使い方 - Qiita</a></li> </ul> <h3 id="コマンドライン引数"><a href="#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%BC%95%E6%95%B0">コマンドライン引数</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/furusin_oriver/items/f030d1eaa9e7b54233c3">Node.jsでコマンドライン引数を取得する - Qiita</a></li> </ul> <h3 id="ファイル・ディレクトリ存在確認"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%BB%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E5%AD%98%E5%9C%A8%E7%A2%BA%E8%AA%8D">ファイル・ディレクトリ存在確認</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.gesource.jp/weblog/?p=8213">node.jsでファイルやディレクトリが存在するかどうかを調べる – 山本隆の開発日誌</a></li> </ul> <h3 id="ファイル書き込み"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF">ファイル書き込み</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://blog.katsubemakito.net/nodejs/file-write">[Node.js] ファイルに書き込む様々な方法</a></li> </ul> <h3 id="標準出力"><a href="#%E6%A8%99%E6%BA%96%E5%87%BA%E5%8A%9B">標準出力</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://maku77.github.io/nodejs/io/stdio.html">標準出力 (stdout)、標準エラー出力 (stderr) への出力 | まくまくNode.jsノート</a></li> </ul> <h3 id="別ディレクトリで yarn 実行"><a href="#%E5%88%A5%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%A7+yarn+%E5%AE%9F%E8%A1%8C">別ディレクトリで yarn 実行</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/hiro4hiro4/articles/cb193f71b2ad26">ルートのpackage.jsonから、yarnで作業ディレクトリを指定してscriptを実行する方法</a></li> </ul> <h3 id="(未使用) 現在ディレクトリの取得"><a href="#%28%E6%9C%AA%E4%BD%BF%E7%94%A8%29+%E7%8F%BE%E5%9C%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E5%8F%96%E5%BE%97">(未使用) 現在ディレクトリの取得</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/Ancient_Scapes/items/6751461d8547200b6715">JavaScript\/Node.jsで現在のディレクトリ名のみを取得する - Qiita</a></li> </ul> <h3 id="(未使用) OS判別"><a href="#%28%E6%9C%AA%E4%BD%BF%E7%94%A8%29+OS%E5%88%A4%E5%88%A5">(未使用) OS判別</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://kantaro-cgi.com/blog/nodejs/nodejs-check-os.html">Node.jsで実行してるOSを判別する方法 - ノウハウブログ - カンタローCGI</a></li> </ul> <h3 id="(未使用) 文字化け"><a href="#%28%E6%9C%AA%E4%BD%BF%E7%94%A8%29+%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91">(未使用) 文字化け</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://hacknote.jp/archives/11522/">node.jsのchild_processをWindowsで使う | ハックノート</a></li> </ul> <h3 id="ARRAy.filter()"><a href="#ARRAy.filter%28%29">ARRAy.filter()</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">Array.prototype.filter() - JavaScript | MDN</a></li> </ul> <h3 id="(未使用) (コマンド) 現在ディレクトリの確認"><a href="#%28%E6%9C%AA%E4%BD%BF%E7%94%A8%29+%28%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%29+%E7%8F%BE%E5%9C%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E7%A2%BA%E8%AA%8D">(未使用) (コマンド) 現在ディレクトリの確認</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://xtech.nikkei.com/it/atcl/column/15/042000103/042200009/">[cd・chdir \/ pwd]カレントディレクトリを知る | 日経クロステック(xTECH)</a></li> </ul> arm-band