Nucleus

ブルートフォースアタックを防ぐために - 2

2007年12月4日

先の記事で書いたこととほぼ同様のことを、今のバージョンのNucleusで実現する方法を考えていたが、以外と簡単にできそう。

まず、確認しておかないといけないのは、現在の Nucleus (ver 3.3) では、パスワードの長さが40文字に制限されていること。これは、非常に長い文字列を用いれば、md5 コリジョン脆弱性を用いて、任意のハッシュ値を生み出すようなパスワードが作成できるかもしれないので、それを防ぐためである。

現在のコンピューターの性能だと、ランダムな40文字の文字列の可能性のすべてをブルートフォースで調べるのはほぼ不可能であろうから、キー長としてはこれでよかろう。

実装には、config.php を若干書き換えるだけである。コアの改造も、これ用のプラグインも要らないし、実装後のコアのバージョンアップも問題なく行える。これを実装することにより、SQLインジェクションでパスワード用のハッシュ値を盗み取るだけでは、ブルートフォースアタックはほとんど不可能になるはずだ。

config.php の『include($DIR_LIBS.'globalfunctions.php');』の前に、次の記述を書き加える。

foreach(array('password','repeatpassword') as $key) {
    if (isset($_POST[$key])) {
        $_POST[$key].='xxxxx';
        $_POST[$key]=substr($_POST[$key],0,40);
    }
}
unset($key);

なお、『xxxxx』の部分はランダムな40バイトの任意の文字列である。例えば、次のようなHTMLを用いれば、これを作成することが出来る。

<html>
<script type="text/javascript">
function addCharToTextBox(targetname,maxlength){
  var target=document.getElementById(targetname);
  var orgText="\n"+target.value;
  if (maxlength < orgText.length) return;
  var newChar=String.fromCharCode(((new Date()).getTime())%94+33);
  if (newChar=="'" || newChar=="\\" || newChar==orgText.substring(orgText.length-1)) return;
  target.value+=newChar;
}
</script>
<body onmousemove="addCharToTextBox('result',40);">
<form>半角で40文字のでたらめな文字列を入力してください。<br />
<input type="text" value="" name="result" id="result" size="60" maxlength="40" onmousemove="" /><br />
<input type="reset" />
</form>
</body>
</html>

あるいは、下のボックスに表示される文字列を用いても良い。
半角で40文字のでたらめな文字列を入力してください。


なお、config.phpの変更を加えた後はログインできなくなるので、ログインした状態でconfig.phpを書き換え、その後に『あなたの設定』からパスワードを書き換えるか、『パスワードを忘れた場合』の認証メールを利用するかのどちらかの方法を用いることになる。複数人数でNucleusを用いている場合は、後者の方法をとることになるはず。

こういった煩雑な手続きなしてランダムな文字列を挿入する状態に移行するためには、コアの書き換えが必要なため、今回は割愛した。

コメント

Kat (2007年12月4日 22:38:27)

当然のことですが、パスワードは容易に類推できないような文字列を選ぶ事が必要です。また、まめに管理操作履歴をチェックして、連続したログインの失敗が無いかどうかを確認した方がよいです。

このあたりに対処するため、サーバへの直接のブルートフォースが効かなくなるようにするプラグインの作成を考えています。

Andy (2007年12月12日 23:02:21)

こういう運用はどうでしょう。
メンバーのテーブルは新しいハッシュ値用に拡張しておきます。コアを書き換えた後,ユーザーがログインしてきたら,そのユーザー名に対して新しいハッシュ値が登録されていればそちらでログインできるかどうか試し,登録されていなければ旧スキームで試して,ログイン可能だったら新しいハッシュ値用フィールドを書き換え,古いのは消してしまうというのは。認証メールなしでできそうな気がするのですが。

Kat (2007年12月13日 10:30:16)

 そうですね。そういった感じのことを考えています。始めは、テーブルの同じカラム(mpassword)を使って、saltありのときはデータの末尾に"salt"と付ける方法など考えていました。しかし、Nucleus のアップグレードスクリプト実行の際のトラブルを出来るだけ軽減するには、新しくカラムを作ったほうがいいかもしれません。
 本家のゴーサインが出たと解釈しているので、コードを書き始めてみます。

コメント送信