あなたがウェブサイトを持っているなら、訪問者がjavascriptユーザースクリプトであなたのサイトを変更しているかどうかをどうにかして知ることができますか?
2 に答える
要するに:EEEEEEK!しないでください!むしろ、何を守る必要があるかを決定し、それを守ります。ポーリング(定期的なチェック)は絶対に避けてください。特に、定期的な重いチェックは避けてください。
すべての変更を追跡できるわけではありません。変更される可能性のあるものが非常に多いため、ほとんどの変更を追跡するのは非常に困難です。
DOMへの変更(新しいノード、削除されたノード、変更された属性)を検出できます。もう1つの回答は、innerHTML
定期的にチェックすることを提案していますが、代わりにミューテーションオブザーバー(Firefox、Chromeでサポート)または古いミューテーションイベント(DOMSubtreeModified
その他)(サポートはイベントによって異なります)を使用することをお勧めします。
すべてのメソッドとプロパティを手動で比較する(eeeek)場合を除いて、標準メソッドへの変更を確実に検出することはできません。Array.prototype.splice
これには、たとえば(そしてArray
もちろんArray.prototype
)を含む大量のオブジェクトを参照し、重いスクリプトを定期的に実行する必要があります。ただし、これはユーザースクリプトが通常行うことではありません。
入力の状態はプロパティであり、属性ではありません。これは、ドキュメントのHTMLが変更されないことを意味します。スクリプトによって状態が変更された場合、change
イベントも発生しません。繰り返しますが、唯一の解決策は、すべての入力を手動でポーリングすることです(eeek)。
イベントハンドラーが接続されているかどうかを検出する信頼できる方法はありません。手始めに、onX
属性を保護し(段落#2)、addEventListener
(ek)への呼び出しを検出し(段落#2のチェックをトリップせずに)、ライブラリ(jQuery.bind
および他のいくつか)によるそれぞれのメソッドへの呼び出しを検出する必要があります。
あなたに有利なことの1つ、そしておそらく唯一のこと:ユーザースクリプトはページの読み込み時に実行されるので(すぐには実行されない)、防御を準備するための十分な時間があります。 それでさえあなたに有利に働くわけではありません(注目してくれたBrock Adamsとリンクに感謝します)
標準のメソッドが呼び出されたことを、独自のメソッド(ek)に置き換えることで検出できます。この方法(eek)でインストルメント化する必要のあるメソッドはたくさんあります。ブラウザーによるものもあれば、フレームワークによるものもあります。IE(およびFirefoxでさえ@Brockに感謝)がDOMクラスのプロトタイプに触れることを許可しないという事実は、「eek」にさらに1つまたは2つの「e」を追加します。一部のメソッドはメソッド呼び出し(戻り値、コールバック引数)を介してのみ取得できるという事実により、さらに「e」が1つまたは2つ追加され、合計で「eeeek」になります。全体をクロールするという考えはwindow
、セキュリティ例外とキャッチできないセキュリティ例外によって失敗します。つまり、iFrameを使用せず、iFrame内にいない場合を除きます。
すべてのメソッド呼び出しを検出した場合でも、に書き込むことでDOMを変更できますinnerHTML
。FirefoxとChromeはMutationObserversをサポートしているため、これらを使用できます。
既存のメソッドへのすべてのメソッド呼び出しを検出してミューテーションをリッスンしても、ほとんどのプロパティはどちらにも反映されないため、すべてのオブジェクトのすべてのプロパティも監視する必要があります。誰かがあなたが決して推測しないキーで列挙できないプロパティを追加しないように祈ってください。ちなみに、これはDOMミューテーションもキャッチします。ES6では、オブジェクトのプロパティセットを監視することが可能になります。ES5の既存のオブジェクトプロパティにセッターをアタッチできるかどうかはわかりません(ES3構文を順守している間)。すべてのプロパティをポーリングするのは簡単です。
もちろん、独自のスクリプトがいくつかの変更を行えるようにする必要があります。ワークフローは、フラグを設定することです(グローバルスコープからはアクセスできません!)「私は合法です」、あなたの仕事をし、フラグをクリアします-すべてのコールバックにも隣接することを忘れないでください。次に、メソッドオブザーバーはフラグが設定されていることを確認します。プロパティウォッチドッグは、変更が有効かどうかを検出するのに苦労しますが、すべての正当な変更についてスクリプトから通知される可能性があります(手動で、ユーザースクリプトがその通知ストリームを表示できないことを確認してください)。イーク。
最初は気づかなかったまったく別の問題があります。ユーザースクリプトはページの読み込み時に実行されますが、iFrameを作成することもできます。ユーザースクリプトが次のことを行うことは完全に考えられないことではありません(しかし、今でもありそうにありません):1)スクリプトブロッカーを検出します、2)軌道からページを削除します(document.body.innerHTML =
少なくとも、大幅に改ざんしない限り、防ぐことはできませんdocument.body
)、3)挿入します元のURLを使用する単一のiframe(サーバー側での二重読み込みを防止しますか?)および4)保護が読み込まれる前に、その空のiframeを操作するための十分な時間があります。
また、Brock Adamsによって発見された複製を参照してください。これは、私がそれを実行する必要があるとは思わなかった他のいくつかのチェックを示しています。
自分で変更するスクリプトがない場合は、document.body.innerHTMLとdocument.head.innerHTLを実際のスクリプトと比較してください。
スクリプトでDOMを変更する場合は、値を更新して比較することができます。setIntervalを使用して定期的に比較します。