0

http://madskristensen.net/post/Brute-force-protect-your-website.aspxのように、失敗したログイン数の制限を介してブルートフォース保護を実装しました。 しかし、2つの問題が発生しています。

  • 一定の時間が経過しても(私の場合は2分)、キャッシュ内のレコードの有効期限が切れておらず、再度ログインできません。これは、関数が失敗した試行の数をチェックするときに、この5分後も最大許容値を取得することを意味します
  • 私が理解したMSDNからのキャッシュは、アプリケーション用の単一のストレージです。私のアプリケーションで見ると、キャッシュはアプリケーションごと、IPごとのようです。なんで?助言がありますか?これが私のコードです:

    int CountOfFailedLoginAttempts()
    {
       if(Cache["L1|"+TextBox1.Text]==null)
       {
           return 0;
       }
       return (int) Cache["L1|" + TextBox1.Text];
    
    }
    void AddFailedAttempt()
    {
        if(Cache["L1|"+TextBox1.Text]==null)
        {
            Cache.Insert("L1|"+TextBox1.Text,1,null,System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0,2,0));
        }
        else
        {
            int tries = (int) Cache["L1|" + TextBox1.Text];
            Cache["L1|" + TextBox1.Text] = tries + 1;
        }
    }
    void ClearFailedAttemptCounter()
    {
        Cache.Remove("L1|" + TextBox1.Text);
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (CountOfFailedLoginAttempts() >= 5)
        {
            Label1.Text = "Login will be unavailable for 2 minutes";
        }
        else
        {
            SqlConnection con =
                new SqlConnection("valid connection string");
            SqlCommand cmd = new SqlCommand("Select top 1 password from users WHERE UserName=@UN", con);
            cmd.CommandTimeout = 600;
            cmd.Parameters.Add(new SqlParameter("UN", TextBox1.Text));
            con.Open();
            string res = (string) cmd.ExecuteScalar();
            con.Close();
            if (res == TextBox2.Text)
            {
                FormsAuthentication.RedirectFromLoginPage(TextBox1.Text, true);
                ClearFailedAttemptCounter();
            }
            else
            {
                Label1.Text = "Wrong password. "+(5-CountOfFailedLoginAttempts()).ToString()+"more attempts and access will be suspended for 2 minutes.";
                AddFailedAttempt();
            }
        }
    }
    

    }

4

2 に答える 2

2

スライド式の有効期限(2分)を使用しています。これは、誰かがその時間内に値を読み取っている間、キャッシュアイテムが残ることを意味します。これは、毎分再試行し続けると、アカウントが永久にブロックされることを意味します。

キャッシュはキャッシュであり、重要なデータストレージではありません。2分間残っているアイテムを当てにすることはできません。サーバーのメモリ不足により、ASP.NETがアイテムをキャッシュから削除する可能性があります。また、すべて独自のキャッシュを持つ複数のワーカープロセス(おそらく複数のマシンに分散している)を提供するWebファーム/ガーデンの可能性もあります。

于 2012-10-07T12:12:21.483 に答える
0

回答ありがとうございます。結局のところ、問題は次の行にあります。

Cache["L1|" + TextBox1.Text] = tries + 1;

メカニズムは思ったよりかなり違います。値を置き換える代わりに、指定されたキーの値をキャッシュから削除し、新しいキーの値を挿入しますが、有効期限の設定はありません。そのため、値が期限切れになることはないように見えました。これは、絶対有効期限モードとスライド有効期限モードの両方に関連しています。私はそのような問題を解決しました:

void AddFailedAttempt()
    {
        if(Cache["L1|"+TextBox1.Text]==null)
        {
            Cache.Insert("L1|"+TextBox1.Text,1,null,System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromMinutes(2));
        }
        else
        {
            int tries = (int) Cache["L1|" + TextBox1.Text];
            Cache.Remove("L1" + TextBox1.Text);
            Cache.Insert("L1|" + TextBox1.Text, tries+1, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(2));
        }
    }

そしてそのようにして、すべてが適切に機能します。

于 2012-10-07T13:11:33.987 に答える