3

ある種の粗雑な JavaScript フラッド防止機能を実装できるかどうか疑問に思っていました。私のコードは AJAX を介してサーバーからイベントを受け取りますが、これらのイベントが非常に頻繁に発生することがあります (私が管理していません)。

私はこれに対抗する方法を考え出そうと試み、小さなスクリプトを書きました: http://jsfiddle.net/Ry5k9/

var puts = {};

function receiverFunction(id, text) {
       if ( !puts[id] ) {
           puts = {};
           puts[id] = {};
       }

       puts[id].start = puts[id].start || new Date();
       var count = puts[id].count = puts[id].count + 1 || 0;
       var time = (new Date() - puts[id].start) * 0.001;

       $("text").set("text", (count / time.toFixed()).toString() + " lines/second");

       doSomethingWithTextIfNotSpam(text);
   }
};

これらの種類の攻撃に対して効果的であると証明できると思いますが、改善または書き換えることができるかどうか疑問に思っていますか?

これまでのところ、1 秒あたり 3 行または 2.5 行を超えるものはすべてスパムのように思えますが、時間が進むにつれて (開始マークが設定されているため... まあ... 最初に)、違反者は単にしばらくアイドル状態になる可能性があります。その後フラッドを開始し、1 分間に 1 行を通過することは事実上ありません。

また、私は Mootools と Lo-Dash ライブラリを使用していることを付け加えたいと思います (おそらくそれらはいくつかの興味深い方法を提供します) が、これがネイティブ JS を使用して実行できる場合は望ましいでしょう。

どんな洞察も大歓迎です!

4

3 に答える 3

1

ネイティブ JavaScript について質問されたことは承知していますが、RxJSをご覧ください。

RxJS または Reactive Extensions for JavaScript は、データ ストリームを変換、構成、およびクエリするためのライブラリです。単純な値の配列から、一連のイベント (不運またはその他)、複雑なデータの流れまで、あらゆる種類のデータも意味します。

そのページには、throttleメソッドを使用して「dueTime の前に別の値が続く監視可能なシーケンスの値を無視する」例があります ( sourceを参照)。

keyup = Rx.Observable.fromEvent(input, 'keyup').select(function(ev) {
            return ev.target.value;
        }).where(function(text) {
            return text.length > 2;
        }).throttle(500)
        .distinctUntilChanged()

毎秒 2.5-3 を取得し、次の秒まで残りのイベントを無視する同様の方法があるかもしれません。

于 2013-05-17T12:10:03.953 に答える
1

他の場所で実装されたソリューションに出会うまで、メッセージのフラッディングを禁止する効果的な対策について熟考するのに何日も費やしました。

まず、ペナルティ変数とスコア変数、および最後のアクションが発生した時点の 3 つが必要です。

var score = 0;
var penalty = 200; // Penalty can be fine-tuned.
var lastact = new Date();

次に、前のメッセージと現在のメッセージの間の距離だけスコアを減らします。

/* The smaller the distance, more time has to pass in order
 * to negate the score penalty cause{d,s}.
 */
score -= (new Date() - lastact) * 0.05; 

// Score shouldn't be less than zero.
score = (score < 0) ? 0 : score;

次に、メッセージ ペナルティを追加し、しきい値を超えるかどうかを確認します。

if ( (score += penalty) > 1000 ) {
   // Do things.
}

その後、最後のアクションを更新することを忘れないでください:

lastact = new Date();
于 2013-06-17T16:22:53.123 に答える