「このリポジトリ見てくれない?」その求人、バックドアかもしれない ― 開発者を狙う偽リクルーター攻撃を解剖する
タグ候補: Security npm Node.js 初心者 キャリア
はじめに
2026年6月、Hacker News(海外エンジニアの巨大掲示板)で1600ポイント超を集めて1位になった記事がある。
フルスタックエンジニアの Roman Imankulov 氏が、LinkedInの偽の求人を装ったマルウェア攻撃を実際に受けて、その手口を解剖したという記事だ。
読んでゾッとした。これは「うっかり者が引っかかる詐欺」ではない。普通に働いている、まともなエンジニアが、油断した日に一発でやられるタイプの攻撃だった。
そして日本語でこれを解説している記事がまだほぼ無い。だから、手口を日本の開発者向けに噛み砕いて、どう守るかまでまとめておく。
この記事は Roman Imankulov 氏のブログ記事「A backdoor in a LinkedIn job offer」を元に、攻撃の仕組みを解説し、日本の開発者向けの防御策を加えたものです。元記事は末尾にリンクしています。
何が起きたのか(30秒でわかる全体像)
1. LinkedInで「リクルーター」からDMが来る
↓
2. 「うちのプロダクトのバグを直してほしい。このGitHubリポジトリ見て」
↓
3. 「deprecatedなNode moduleの問題があるから npm install して確認して」
↓
4. 言われた通り npm install した瞬間 → あなたのPCで悪意あるコードが実行される
↓
5. 攻撃者のサーバーから送られてきたコマンドが、あなたのPCで何でも実行される
ポイントは、「コードを実行する」必要すらないこと。
npm install という、エンジニアが1日に何回も打つあの普通のコマンドだけで発火する。ここが恐ろしい。
手口の解剖
トリック1:npm install だけで悪意あるコードが走る仕組み
多くの人が「コードは node app.js で実行して初めて動く」と思っている。
でも npm には ライフサイクルスクリプト という仕組みがあって、その中の prepare は npm install した直後に自動で実行される。
package.json がこうなっていたとする:
{
"scripts": {
"prepare": "node app/index.js"
}
}
この場合、依存パッケージをインストールしただけで node app/index.js が勝手に走る。
攻撃者は、この app/index.js の中に「悪いコードを呼び出す処理」を仕込んでおく。
つまり「リポジトリを動かしてみよう」とすら思っていなくても、npm install した時点で終わっている。
トリック2:テストコードに偽装して隠す
悪意あるコードは、app/test/index.js という、いかにもテストファイルっぽい名前の中に隠されていた。
しかも約250行の、コメントアウトされたテストコードの「壁」の中に、たった1行だけ本物のペイロードが紛れ込ませてあった。
パッと見では「初心者が書いた雑なテストコード」にしか見えない。レビューする気も失せるような見た目にして、人間の目を滑らせるのが狙いだ。
トリック3:通信先URLをバラバラに分解して隠す
普通、コードの中に https://あやしいサイト.com みたいなURLが直書きされていれば、検索ですぐ見つかる。
そこで攻撃者は、URLをバラバラの破片に分解して組み立てるようにしていた。イメージはこんな感じだ:
// 一見、意味のない変数の羅列に見えるが…
const a = "https";
const b = "://";
const c = "あやしいドメイン";
const d = "/icons/";
// これらを後で連結して、本当の通信先URLを組み立てる
const url = a + b + c + d + "77";
こうすると、ソースコードを「URLっぽい文字列」で検索しても引っかからない。
そして組み立てたURLにアクセスし、サーバーが返してきた内容を、そのまま自分のPCで実行するようになっていた。サーバー側がコマンドを送れば何でも実行できる、という状態だ。
トリック4:実在する他人になりすます
ここが一番ゾッとする部分。
- コードのコミット履歴は、実在するエンジニア(普通のLinkedIn・GitHub・個人サイトを持つ人)の名前とメールアドレスで偽装されていた。本人に聞いたら「そんな会社で働いたことない。なりすまされた」と。
- リクルーター本人のプロフィールは、実在する有名な「芸術ジャーナリスト」のものを盗用していた。技術とは何の関係もない人だ。
しかも著者が「インストールできないんですけど」とカマをかけたら、そのジャーナリストのはずのリクルーターが、急にNode.jsのバージョン談義を始めて「npm installした?」と食い下がってきたらしい。中の人は当然、技術者の攻撃者だ。
なぜこれが「誰にでも起こる」のか
著者はセキュリティに明るい人で、最初のDMの時点で違和感を覚えていた。それでも正直にこう書いている。
「疲れていたり急いでいたりする日だったら、考える前に npm install を打っていたかもしれない」
これは本当にそうだと思う。
- 転職を考えていれば、リクルーターのDMは無視しづらい
- 「コードレビューしてほしい」は、実務でも普通にある依頼
-
npm installは無意識に打つコマンド
正常な判断力がある人でも、文脈と疲労が重なれば刺さる。だからこそ怖い。
これは「Contagious Interview(伝染する面接)」と呼ばれる攻撃キャンペーンの典型的な手口だ。MicrosoftやSocketなどのセキュリティ企業が北朝鮮の国家支援グループの仕業として高い確度で特定している。
- 偽リクルーターは、暗号資産(crypto)企業やAI企業を名乗ることが多い
- 「コーディング課題」「PoCのレビュー」を口実に、リポジトリを clone & 実行させる
- 2024年末以降、数百個の悪意あるnpmパッケージがばらまかれ、ダウンロード総数は数万回に及ぶ
- 狙いは技術者個人のPCにあるSSHキー・クラウド認証情報・GitHubトークン・署名鍵・暗号資産ウォレット
ターゲットが技術者本人なのは、開発者のPCには「会社のインフラへの鍵」が詰まっているからだ。一人の開発者を踏み台にすれば、その会社のクラウド環境やCI/CDパイプラインまで侵入できてしまう。
実は今、npm自身がこの問題に動き出している(2026年6月の最新動向)
この攻撃が成立する根本原因は、「npm install が、パッケージのスクリプトを自動で実行してしまう」という長年の仕様にある。
そして2026年6月9日、ついに GitHub(npmの運営元)が動いた。次期メジャーバージョン npm v12 で、インストール時のライフサイクルスクリプトをデフォルトで無効化すると発表したのだ。
GitHubはこの仕様を「npmエコシステムで最大のコード実行の入り口(single largest code-execution surface)」と表現している。つまり、まさに今回のような攻撃が多発したからこそ、npm本体が「デフォルトで危険」という状態をやめる方向に舵を切ったわけだ。
- npm v12 では、
npm installが依存パッケージのpreinstall/install/postinstallスクリプトを、明示的に許可しない限り実行しなくなる - git・file・link 依存の
prepareスクリプトも同様にブロックされる - v12のリリースは2026年7月ごろの見込み
裏を返せば、v12が来るまでは「npm install は自動でコードが走る」前提で自衛する必要があるということだ。次の章で、その具体策を見ていく。
日本の開発者向け:どう守るか
ここからが本題。知らないコードを触るときの現実的な防衛策をまとめる。
防御1:知らないリポジトリは「使い捨て環境」で開く
自分のメインPCで git clone → npm install をいきなりやらない。
- 使い捨てVPS(Hetzner、さくらVPSなど、数百円で借りて終わったら捨てる)
- Dockerコンテナ(隔離された箱の中で動かす)
- GitHub Codespaces などのクラウド環境
これらの「隔離された箱」の中なら、最悪バックドアが動いても、あなたのメインPCの認証情報までは届かない。
防御2:npm install でスクリプトを自動実行させない
これは今日から使えるテクニック。インストール時にライフサイクルスクリプトを無効化するオプションがある:
npm install --ignore-scripts
prepare や postinstall といった「自動で走るスクリプト」を止められる。
普段から .npmrc に設定しておくこともできる:
# ~/.npmrc
ignore-scripts=true
ただし、この設定には副作用がある。 bcrypt・canvas・node-sass のようなネイティブモジュール(C++アドオンをビルドする正規パッケージ)は、インストール時スクリプトに依存しているため、ignore-scripts=true を入れると軒並みビルドに失敗する。
「環境が壊れたから設定を外す」と元の木阿弥になるので、信頼できるパッケージだけ個別にビルドを許可する運用にするのが現実解だ:
# 信頼できるパッケージだけ、後から個別にビルドを実行する
npm rebuild bcrypt
こうすれば、「デフォルトは自動実行しない/信頼できるものだけ手動で許可する」という安全な状態を保てる。
※ 補足:--ignore-scripts は今回の攻撃の発火点(prepare)はきちんと止められる。ただし「これさえ付ければnpmのあらゆる攻撃を防げる」わけではない。たとえばgit依存パッケージが独自の .npmrc でgit実行ファイル自体を差し替えると、--ignore-scripts を付けてもコードが走る抜け道が知られている(これも npm v12 で塞がれる予定)。だから単体の対策に頼らず、防御1〜5を重ねるのが安全だ。
防御3:package.json の scripts を最初に見る
知らないリポジトリを開いたら、まず package.json の scripts セクションを人間の目で確認する。
"scripts": {
"prepare": "node app/index.js", // ← なぜ prepare でアプリ本体を実行する?怪しい
"postinstall": "node ./setup.js" // ← インストール後に何を走らせている?
}
prepare / postinstall / preinstall で見慣れない処理が走っていたら警戒する。普通のライブラリはここでアプリ本体を起動したりしない。
防御4:AIエージェントに「読み取り専用」でレビューさせる
これは元記事の著者がやって「自分で読むより速かった」と書いていた方法で、僕も推したい。
ポイントは、ファイルの読み取りだけ許可して、コードの実行は絶対させないこと。Claude Code などのエージェントでも、ツールを読み取り系(read / grep / find / ls)だけに絞って、
「このコードベースをレビューして、怪しい挙動・難読化・外部通信・自動実行されるスクリプトを全部フラグして」
と頼めば、人間が250行のダミーコードを読み疲れる前に、隠されたペイロードを数秒で見つけてくれる可能性が高い。
重要: このとき、エージェントにファイル書き込みやシェル実行を許可してはいけない。「読むだけ」に徹させること。バックドアの目的は「コードを実行させること」なので、実行させなければ無力化できる。
さらに踏み込むなら、AIエージェント自体も隔離環境(Dockerコンテナや使い捨てVPS)の中で起動するのが理想だ。エージェントが動くワークスペースにシェル実行や書き込み権限が残っていると、解析中に誤って、あるいはコード内に仕込まれた指示(プロンプトインジェクション)によってペイロードを実行してしまうリスクが残る。「怪しいコードは、AIに見せるときも隔離した箱の中で」を徹底したい。
防御5:そもそも怪しい兆候を覚えておく
- 知らないリクルーターが、いきなり「このコード直して/レビューして」と実コードを触らせようとする
- 「とりあえず
npm installして動かして」と実行を急かす - 会社の実体が薄い(crypto系スタートアップを名乗ることが多い)
- リクルーターのプロフィールが、技術と無関係なのに技術的な話に食い下がる
ひとつでも当てはまったら、いったん手を止めて疑う。これだけで大半は防げる。
なお、これらの防御はあくまで「個人の注意力」に依存している。チームや会社として守るなら、開発機材へのEDR導入や、不審な外部への通信を制限するといったネットワーク・インフラ層での多層防御も併せて検討したい(本記事では個人開発者向けの対策に絞る)。
まとめ
| 攻撃のポイント | 防御 |
|---|---|
npm install の prepare で自動発火 |
--ignore-scripts を使う(+必要なものは npm rebuild) |
| テストコードに偽装して隠す |
package.json の scripts を最初に見る |
| URLを破片に分解して難読化 | 読み取り専用AIエージェントでレビュー |
| 実在他人のなりすまし | 「使い捨て環境」でしか触らない |
| 疲れている日に刺さる | 怪しい兆候を覚えて、手を止めて疑う |
転職市場が活発な今、エンジニア本人を狙うこの手の攻撃は今後も増える。
「知らないコードは、自分のPCでいきなり動かさない」 ― これだけ覚えて帰ってほしい。
参考リンク
- Roman Imankulov, "A backdoor in a LinkedIn job offer"(元記事・英語) https://roman.pt/posts/linkedin-backdoor/
- Microsoft Security Blog: "Contagious Interview: Malware delivered through fake developer job interviews"(攻撃キャンペーンの公式解説・英語) https://www.microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews/
- Socket: "North Korea's Contagious Interview Campaign"(継続的な脅威分析・英語) https://socket.dev/supply-chain-attacks/north-korea-s-contagious-interview-campaign
- npm v12 のインストールスクリプト無効化について(2026年6月発表・英語) https://thehackernews.com/2026/06/github-to-disable-npm-install-scripts.html
- npm公式ドキュメント: scripts(ライフサイクルスクリプトの仕様) https://docs.npmjs.com/cli/v8/using-npm/scripts
この記事は海外の事例を日本の開発者向けに解説したものです。手口の発見・調査は元記事の著者によるものであり、本記事は防御の観点から再構成しています。