00:00:00(キーボードのタイピング音) それでは、今話題になっているHoneyの大スキャンダルについて見ていきたいと思います。
00:00:12Honeyをご存じない方のために説明すると、
00:00:14Honeyはクーポン系のChrome拡張機能の一つで、
00:00:17つまりそのコードはすべて私が閲覧できる状態になっています。
00:00:19だから、
00:00:20これらのYouTube動画で主張されている内容を実際に確認して、
00:00:23本当に起きているのかどうかを見ることができるんです。
00:00:26さらに拡張機能の場合、
00:00:27時系列で追跡して、
00:00:29こうした悪質な判断が実際に行われていたのか、
00:00:32そしてソフトウェアエンジニアたちがそれを継続するだけでなく、
00:00:36これらの悪質な動作をより優れた、
00:00:39より堅牢なものにするための変更を加えてきたのかを確認できます。
00:00:44答えはイエス、確かにそうしてきました。
00:00:45そして、それがどのように行われてきたかをお見せします。
00:00:47でも、皆さんの中には何が起きているのか全く知らない方もたくさんいると思います。
00:00:50Honeyについてもあまり詳しくないかもしれません。
00:00:52だから、これまでの経緯を追えていないんですよね。
00:00:55これは実際、Honeyの非常に特定の動作に関わることなので、それについて説明したいと思います。
00:00:59というわけで、最新のHoney暴露動画から3分間の抜粋を見ていきます。
00:01:05その後、
00:01:05ミニファイされたコードを調べて、
00:01:07私が発見したことと、
00:01:08その背後にある意図について話します。これがちょっと驚きなんです。
00:01:12さて、人々が欺瞞よりも嫌うものが一つあるとすれば、それは窃盗です。
00:01:15そして最初の動画で、Honeyがインフルエンサーからお金を盗んでいる様子をお見せしました。
00:01:19しかし、お伝えしていなかったのは、この行為がほとんどの場合、厳格に禁止されているということです。
00:01:25つまり、
00:01:25この業界を運営する企業、
00:01:26アフィリエイトネットワークは、
00:01:28Honeyのようなクーポン拡張機能がインフルエンサー、
00:01:31ブロガー、
00:01:31その他コンテンツ主導のアフィリエイトから報酬を横取りする可能性が高いことを十分に理解しています。
00:01:37さらに重要なのは、
00:01:38彼らもこれが不公平であることを理解しているということです。特に業界標準として残っている
00:01:43「ラストクリック優先」
00:01:44ポリシーの下ではなおさらです。
00:01:46この種の報酬窃盗を防ぐため、
00:01:47主要なアフィリエイトネットワークのほとんどは「スタンドダウンポリシー」として知られるものを施行しています。
00:01:53Honeyでそれがどのように機能するかお見せしましょう。
00:01:55まず、アフィリエイトリンクなしでnewegg.comにアクセスしてみます。
00:01:58ご覧のとおり、Honeyがすぐにポップアップしてキャッシュバックを提供します。
00:02:02しかし、
00:02:02今度は私のNeweggアフィリエイトリンクを使ってこれをもう一度やってみると、
00:02:06Honeyが全くポップアップしないことに気づくでしょう。
00:02:08そしてHoneyアイコンをクリックすると、Honeyが無効化されているのがわかります。
00:02:12これが、ユーザーが既に他の誰かのアフィリエイトリンクをクリックしている場合のHoneyの本来の動作です。
00:02:17では、疑惑の詐欺はどこにあるのか、とお尋ねでしょう?
00:02:20実は、
00:02:20Honeyには常にスタンドダウンシステムがアプリに組み込まれていましたが、
00:02:25いつ、
00:02:25誰に対してルールを適用するかを選択的に決めてきたのです。
00:02:28私のNeweggアフィリエイトリンクをもう一度テストしてみましょう。
00:02:31ただし今回は、
00:02:32完全に別々の2つのChromeブラウザを同時に開いていて、
00:02:35それぞれ異なるHoneyアカウントにログインしています。
00:02:38左側のHoneyアカウントはキャッシュバックポイントがゼロで、
00:02:41右側のHoneyアカウントはキャッシュバックポイントが貯まっています。
00:02:45では、両方のブラウザでNeweggアフィリエイトリンクを開くと何が起こるでしょうか?
00:02:49左側のHoneyアカウントは最初と同じようにスタンドダウンします。
00:02:52しかし見てください、キャッシュバックポイントを持っている右側のアカウントは、スタンドダウンしませんでした。
00:02:58では、なぜそうなるのでしょうか?
00:02:59これが私がテストしたかったことなんです。
00:03:01これを調べたかったんです。なぜならこれはコードだからです。
00:03:03私はコードを理解できます。
00:03:05送られてくるJSONを見れば、理解できます。
00:03:09それだけでなく、
00:03:10AIの力を使えば、
00:03:11私のこれまでのプログラミング人生では考えられなかったスピードでミニファイされたコードを検索できるんです。
00:03:18そこで私たちがやったのは、まずHoneyの多数のバージョンを入手することでした。
00:03:22私が調べたのは、だいたい2019年2月頃から現在まで、バージョン1901までです。
00:03:29そして、
00:03:29まず最初に確認したかったのは、
00:03:31このユーザーポイントのようなものがスタンドダウンメニューを表示するかしないかを決めているのか、
00:03:36それは存在するのか、
00:03:37ということでした。
00:03:38はい、確かに存在していました。
00:03:40しかし本当の疑問は、それが変更されてきたのか、ということでした。
00:03:43私は大企業で働いていたので、
00:03:44大企業で働いた経験があるんですよ。皆さんも働いたことがあるでしょうし、
00:03:47何人かはあると思いますが、
00:03:48時々コードがそのまま残っていることがあるのを知っていますよね。
00:03:50ほら、まるで「おっとっと」って感じで、まだそこにあって、5年間誰も変更していない、それがただの現実なんです。
00:03:55そして、それが私が探していたものでした。つまり、コードがそのまま残っているのか?
00:04:00それとも、重大な変更があったのか?
00:04:03小さなバグ修正みたいなものではなく。
00:04:05さて、
00:04:05著作権侵害を避けるために、
00:04:07というのもPayPalの弁護士が実際にコードを見せる人にDMCAで著作権侵害の申し立てをするらしいので。
00:04:13つまり、何が起きていたのかを見せるために、古い黒板で奇妙なジェスチャーゲームをしなければならないということです。
00:04:18それで、
00:04:19バージョン11から始めますが、
00:04:20覚えていますか、
00:04:212019年頃ですね、
00:04:22このバージョンにはスタンドダウンロジックがありました。
00:04:25SSDスタンドダウンロジックと呼ばれるものさえありました。
00:04:29大量のデータを含むJSONファイルと照合していました。
00:04:32これが、全くログインしていないユーザーのスタンドダウン、最も基本的なものです。
00:04:38ここで、UPはユーザーポイントを意味します。
00:04:41ADBは広告ブロックの最終使用時刻のようなものです。
00:04:45アカウントログイン状態もあります。
00:04:47そして、時々現れる他のフィールドもあります。
00:04:50興味深いのは、2019年のバージョン11では、物事がよくこのような感じだったことです。
00:04:55巨大なswitch文があって、最終的にこれらのケースがあり、「さて、メールアドレスをテストするか?」みたいな感じです。
00:05:02そして、文字通り文字列がありました。
00:05:04このメールアドレスに「test」が含まれているか?
00:05:06そうなら常にスタンドダウン、ちなみに、これは怪しいです。
00:05:10これらのリンクテストアカウントが入ってきて、
00:05:12リンク共有テストのように「これは実際に機能するか?」を確認できないようにしているんです。
00:05:16正直言って、ここにいる誰が「test」を含まないテストアカウントを持っていないでしょうか?
00:05:20私も確実に持っています。
00:05:22しかしながら、これは明示的なチェックでした。
00:05:24メールアドレスのどこかに「test」という単語があれば、無効化されます。
00:05:29しかし、
00:05:29それ以上に、
00:05:30つまり、
00:05:30これはすでに話されていましたが、
00:05:32それ以上に本当に混乱していたのは、
00:05:34一連のチェックを通過して、
00:05:35「現在アクティブなプロバイダーがLS、
00:05:38つまりリンクシェアと等しいか?」という感じだったことです。
00:05:41もしそうなら、これらの正確なルールを適用してほしいのです。
00:05:44そして後で、
00:05:45解明したすべてのルールを調べるチェックがあり、
00:05:48小さなforループで一つ一つのルールを調べて、
00:05:52どれかが失敗するかをチェックしていました。
00:05:55どれかが失敗すれば、スタンドダウンします。
00:05:57ご覧のとおり、
00:05:58これはかなりハードコードされたプロセスでした。なぜなら、
00:06:01「もしリンクシェアなら、
00:06:02このアクションを実行」のような文字通りの行があったからです。
00:06:06「もしこの他のプロバイダーなら、別のことをする」という感じです。
00:06:08もちろん、私はこの種のことが起こる多くのプロジェクトに参加してきました。
00:06:12これは完全に普通のことです。
00:06:14最初は「よし、プロバイダーが1つか2つあるかもしれない、それだけだ」という感じで始めます。
00:06:18だから、ここに少しのハードコードされたエッジケースを入れて、物事が確実に特定の方法で処理されるようにするだけです。
00:06:24ある程度の期間スタンドダウンしますが、ちなみに、それはあまり長い期間ではありませんでした。
00:06:27ルールが実際にどれほどひどかったかを知るには、MegaLegの動画を見るべきです。
00:06:34しかし、
00:06:34繰り返しになりますが、
00:06:35私の目標は「彼らがバグ修正のためにコードに変更を加えたのか?何が起こったのか?」ということです。
00:06:39何が起こったのか?
00:06:40さて、
00:06:40ここで少し混乱してきます。なぜなら、
00:06:43バージョン11から14の間、
00:06:452022年まで続いたと思いますが、
00:06:48そう、
00:06:492022年、
00:06:50物事はほぼ一定のままでした。
00:06:52実際にはほとんど変わらず、少しの編集があっただけで、あまり見せるほどのものはありませんでした。
00:06:56しかし、
00:06:57バージョン16あたりから、
00:06:58つまり2024年に、
00:07:00Honey内のエンドポイントからこれらの決定の多くを駆動できるような堅牢なリファクタリングが行われました。
00:07:07このエンドポイントは、このベース値を持ち、これらの値を持ち、そしてXの下にこれらの値を持つオブジェクトを送信します。
00:07:16つまり、以前のバージョンでは、実行したい動作の種類を決定するために、一連のif文を使用していたということです。
00:07:23そして、ルール評価を行い、このルールが実際に通ったかどうかを確認していました。
00:07:28実際にtrueかfalseが返されたのか、と。
00:07:30しかしバージョン16で、彼らはソフトウェアエンジニアリングの面でもう少し本格的に取り組むことにしました。
00:07:36データをラップしたり、
00:07:37オブジェクトに基本的な変更を加えたりするようなif文の塊がある場合、
00:07:42どうすればいいか、
00:07:43皆さんご存知ですよね?
00:07:45そういう時は、何らかの設定ファイルを通して処理させるでしょう。
00:07:48もう少し扱いやすくするために、より動的な仕組みを通して処理させたいはずです。
00:07:52そして、まさにそれを彼らは実行しました。
00:07:53ここに戻って、
00:07:54ログインしていない私のHoneyユーザーから送られてくるデータを見ると、
00:07:58ベースクラスがあることがわかります。
00:08:00このベースクラスが、Honeyがどう判断するかの基礎となるオブジェクトになります。
00:08:05現時点でこのログインしていないユーザーのベースクラスでは、
00:08:09Honeyが引き下がらないためには65,
00:08:11000ユーザーポイントが必要です。
00:08:1365,
00:08:14000ポイント未満の場合、
00:08:15私はログインしていないのでゼロポイントですが、
00:08:16システムは「申し訳ありませんが、
00:08:17引き下がります」と言うわけです。
00:08:18これを回避しているんです。
00:08:20さて、そのベースを取得すると、次に行うのは、どうやってここに来たのかをチェックすることです。
00:08:25どこから来たのか?
00:08:27なぜここに来たのか?
00:08:28そして次のチェックを行います。これはアフィリエイトネットワークのいずれかから来たものか、と。
00:08:32そして、物事をラップし始めます。
00:08:33つまり、もし私がリンクシェアの場所から来た場合、必要なポイントは5,001だけになります。
00:08:40このベースオブジェクトを編集するわけです。
00:08:41実際には、より優れた、より洗練されたエンジニアリングを行っているんです。
00:08:44もはや一連のハードコードされたif文ではありません。
00:08:48代わりに、実際に「ベースを取って」と言っているわけです。
00:08:51そして、「私のプロバイダーを持っているか?」と聞きたい。
00:08:55プロバイダーを持っている場合、そのプロバイダーの値、または空のオブジェクトを展開したいわけです。
00:09:01そして、さらにワイルドなことをしました。それは、Xの下にあるこれら全てです。
00:09:07これらは全てストア固有の値です。
00:09:09そして、現在どのストアにいるかをチェックして、その値も加えたいわけです。
00:09:17そして、基本的なルールロジックを実行し、もはや何らかのメンテナンスモード下にないことを示します。
00:09:2310年近く存在してきたこのハードコードされたハッキーなものではもはやないことを示しているんです。
00:09:29代わりに、彼らはそこから進化しました。
00:09:31そして2024年、彼らはこう言ったんです。「もっと堅牢にする必要がある。
00:09:33より多くのストアやプロバイダーについて、より保守しやすい方法で、より多くの判断ができるようにする必要がある」と。
00:09:43これはソフトウェアエンジニアリングの仕事であり、彼らはそれを実現しました。
00:09:46だから私がこれを見て感じるのは、
00:09:48時間をかけて、
00:09:48彼らはシステムをより良くするための変更を加えてきたということです。つまり、
00:09:52その背後には意図があるということです。
00:09:54システムが行っていることが詐欺的であろうとなかろうと、それを維持したいと考えているのです。
00:09:59それが詐欺かどうかは私には言えません。それは他の誰かが決めることですが、
00:10:03少なくとも彼らの決定はそれをより堅牢で優れたものにすることだったと言えます。
00:10:07そして、
00:10:07このシステムがかなり怪しいという一般的な認識があることを考えると、
00:10:12彼らはその怪しいシステムを大幅に、
00:10:14大幅に改善したわけです。
00:10:16しかし、私が見つけたのはそれだけではありません。
00:10:17他にも興味をそそられるものを見つけました。
00:10:19VIMという単語が何度も出てくるのを見続けていました。
00:10:23VIM、テキストエディタが何をしているんだ、と思いました。
00:10:26Claude Coteに聞いてみると、
00:10:28実際に「Honey内で見つかったVIMインスタンスマネージャーについて話していますね」と言われました。
00:10:34私は「VIMインスタンスマネージャー。
00:10:35それはあり得ない。
00:10:37それじゃない」と思いました。
00:10:38そして、
00:10:39これを調べ始めると、
00:10:40Honeyプラグインの内部で動作する完全なJavaScript in JavaScriptエンジンがあることがわかりました。
00:10:49さて、これは私が今まで見た中で最も奇妙なものです。
00:10:54それについて少し調べてみました。
00:10:56私はChromeのプラグイン開発の専門家ではありません。
00:10:59だから、なぜ誰かがJavaScriptの中でJavaScriptを実行するのか、まったく理解できませんでした。
00:11:05しかしHoneyがやっているのは、
00:11:07実際にはAcornを使っています。これはJavaScriptパーサーで、
00:11:11有効なJavaScriptからASTを生成します。
00:11:14そしてこれを取り、JavaScriptを評価し、それをこのVIMエンジンに送り込むのです。
00:11:19コード内にはいくつかの参照があり、
00:11:21実際にはcart ops retrieval JSやproduct ops retrieval JSという別のオブジェクトを指しています。これらは時にnullではなく、
00:11:29実際にコードを含んでいることがあります。
00:11:31そして、
00:11:32このJSコードも参照していて、
00:11:33これもまた時にはnullではなく、
00:11:35ちょうどここのように実際の本物のJavaScriptなんです。
00:11:38でも私が確認した限り、実際にはこのコードを実行していないんです。
00:11:41ブレークポイントをいくつか設定してみました。
00:11:42実際にトリガーを作るところまでは到達しませんでしたが、それでもこれは存在しています。
00:11:47彼らは、
00:11:48Honeyから返されるものに基づいて、
00:11:50あなたのマシン上でリモートコードを実行できる仕組みを、
00:11:54非常に非常に難読化された方法で整えているんです。
00:11:57このJavaScript in JavaScript、彼らはJavaScriptパーサーを持っています。
00:12:00JavaScriptの仮想マシンを持っています。
00:12:03JavaScript内の実際のJavaScriptなんです。
00:12:06でも、彼らはこの一つのセクションも持っていて、そこには文字列化された関数がずらりと並んでいます。
00:12:11そして、ページを検索する方法で埋め尽くされた大量のインラインJavaScriptがあります。
00:12:18でも、それらの関数は製品と一緒にダウンロードされます。
00:12:22だから、技術的には古いGoogleの利用規約には違反していないんです。
00:12:26というのも、
00:12:27manifest V3の追加要件を見ると、
00:12:29これをやっている人は誰でもJavaScriptのevalを使用すべきではないとされているからです。
00:12:33わかりました、じゃあそれはやりません。
00:12:34evalは使いません。
00:12:35その代わりに、他のプラグインに知られたくない操作をハードコードします。
00:12:40そして、それらを実行するためにJavaScriptエンジン全体を組み込んで、やっていることをさらに難読化するわけです。
00:12:47面白いのは、
00:12:48このV3はHoney専用に設計されたように見えることです。なぜなら
00:12:51「リモートソースから取得した複雑なコマンドを実行するインタープリターを構築すること、"
00:12:55たとえそれらのコマンドがデータとして取得されたとしても」と書いてあるからです。
00:12:59だから彼らはそれを回避しているんです。
00:13:00これらはリモートのものではありません。
00:13:01Honey拡張機能内で実際に利用可能な文字列なんです。
00:13:05でも、これはとんでもない難読化です。
00:13:07これは本当に奇妙なものです。
00:13:09私個人としては、これが実際に起きている理由を一つも理解できません。
00:13:14先ほど言ったように、どうやら他の拡張機能との相互作用のためらしいです。他の拡張機能というのは広告ブロッカーのことです。
00:13:19どうやら広告ブロッカーは、
00:13:20Honey拡張機能が特定の関数を直接実行すると、
00:13:23それを広告ブロックしてしまう可能性があるようですが、
00:13:26この奇妙なインタープリターを通すことで、
00:13:28検出を回避して実際に動作させることができるようです。
00:13:31わかりませんが、私にはめちゃくちゃな祭りのように見えます。
00:13:34そして、これは本当に非常に興味深いと思いました。なぜなら、私はリバースエンジニアリングを一度もやったことがないからです。
00:13:37他人のソースコード、特にミニファイされたソースコードを本格的に見たことがありませんでした。
00:13:41ただ皆さんにこれを見せたかったんです。
00:13:42これはおそらく私の人生で見た中で最も異常なエンジニアリングです。
00:13:46私は1万行以上もある奇妙なステートマシンで、
00:13:50扱いにくく、
00:13:50理解するのが難しいコードベースに関わったことがありますが、
00:13:55これはそれを上回ります。
00:13:57これは私が今まで見た中で最も複雑で、最も奇妙な装置、ルーブ・ゴールドバーグ級のものに違いありません。
00:14:03さらに、スタンドダウン機能のための動的ルールは堅牢です。
00:14:08その目的が詐欺的であるかないかにかかわらず、
00:14:11ストアごと、
00:14:12プロバイダーごと、
00:14:14ユーザーごとにJSONを介して動的に制御されるように設計されています。
00:14:19とにかく、Magalegaに特別な感謝を送りたいです。
00:14:21本当に素晴らしかったです。
00:14:22彼とチャットする機会がありました。
00:14:23彼はいくつかのことを調べるのに少し手伝ってくれました。
00:14:25だから彼に大きな感謝を。
00:14:26ぜひ動画をチェックしてください。
00:14:27説明欄にあります。
00:14:28とてもよくできています。
00:14:29複数の動画があるので、全部見ることをお勧めします。
00:14:32本当に本当に良いです。
00:14:33それと、私がやったこと、気に入りましたか?
00:14:35このフォーマット、気に入りましたか?
00:14:36わかりません。
00:14:37これは結構新しいんです。
00:14:38これはただ私が配信で時間を過ごして楽しんで、それを皆さんに報告しているだけです。
00:14:42もし配信にいたら、これがライブで起こるのを見れたでしょう。
00:14:44皆さんにとってもっと楽しかったかもしれません。
00:14:45タイトルは「私はリバースエンジニアではないけれど」ですが、これは本当に楽しかったです。
00:14:50人々がこれをやる理由がわかります。
00:14:51じゃあね。
00:14:52おい、それHTTPか?
00:14:55そんなもの、ここから消えろ。
00:14:56そんな方法でコーヒーは注文しない。
00:14:57コーヒーはSSH経由で注文するんだ、terminal.shopでな。
00:15:00本物の体験が欲しいか?
00:15:02本物のコーヒーが欲しいか?
00:15:03二度と思い出す必要のない最高のサブスクリプションが欲しいか?
00:15:06それとも、限定ブレンド、限定コーヒー、限定コンテンツが欲しいか?
00:15:12それなら、CRONをチェックしろ。
00:15:13SSHが何か知らないって?
00:15:14だったら、このコーヒーは君には向いてないかもな。
00:15:18♪ ターミナルコーヒーを手に ♪ ♪ 夢の中で生きる ♪