プログラミングしたり。

HTML/CSS/JavaScript/PHPを中心にWebサイト作ったり。Webサービス作ったり。

octopressを使う

Octopressを使って無料ブログを作成しましたので、その手順を説明します。 エディタとgitで管理できるので、便利かなーと思い、導入してみました。 この記事がOctopressで書く初めての記事になります。

Gitコマンドまとめ

Gitはファイルを作成したり、変更したりしたときの履歴をバージョン管理できます。
以下、3つのエリアを用いて管理していきます。 1.作業ディレクトリ
2.ステージングエリア
3.リポジトリ

Php Security

現在、Webサービスを作成しようと奮闘中です。
おそらく、セキュリティ対策という話をすると、色々と考慮すべきことがあるのだ思いますが、勉強教材にしているドットインストールさんの「ユーザー管理をするWebサービスを作ろう」で話に挙っていたものをまとめました。

htmlspecialchars関数
クロスサイトリクエストフォージェリ(CSRF)対策
セッションハイジャック対策

htmlspecialchars関数

HTMLには特殊な意味を持つ文字があり、
その文字をHTMLでの意味としてではなく、文字として表示するための関数。
フォームなどからの悪意のある入力を無害化し、安全性を高めることができます。
これを行わないとフォームにHTMLタグを入れることができるため、
入力・送信された文字列によって、サイトのレイアウトが崩壊したり、ハッキングされたりして危険です。

対策

htmlspecialchars('文字列', 'エスケープ種類', '文字コード');

ちょっとコードが長いので、この関数を使用するときは、
下記のようなfunctionを作成しておくと便利。
こうすることで、エスケープしたい文字があれば、h()を使用すればOKになる。

function h($s){
    return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
}
エスケープ種類 説明
ENT_COMPAT ダブルクォートを置き換える
ENT_QUOTES ダブルクォート、シングルクォート共に置き換える
ENT_NOQUOTES ダブルクォート、シングルクォート共に置き換えない

クロスサイトリクエストフォージェリ(CSRF)対策

ざっくり一言でいうと、不正なPOSTを防ぐための対策。
「フォームのある画面が表示されたときにフォームに対して
トークンと呼ばれるIDを埋め込んでおき、フォームがPOSTされたときに
設定したトークンと一致しているかを確認する」ということみたいだが、
なんのこっちゃ意味不明。

ドットインストールさんでも、気になる方は調べてみてねと
言っていたのでもうちょっと調べてみた。

CSRFとはなんぞや?

CSRF(シーサーフ)はリクエスト強要と呼ばれる
Webアプリケーションの脆弱性の一種だそうで…

例えば、ユーザが掲示板にログインして何かを書き込むという操作は
ユーザが意図しているため、問題ありません。
しかし、このCSRFというのは悪意のあるサイト(CSRFが仕掛けられているサイト)にアクセスしただけで、掲示板に勝手に書き込みがされてしまうというもの。

本来であれば、掲示板にログインして、
そこで入力した書き込みが反映されるというのが正しいですが、
掲示板以外からの投稿ができてしまうんですねー。
CSRF対策というのは、こういう外部からのPOSTを防ぐ!
掲示板からのPOSTのみ受け付ける!ようにするものみたいです。

対策

トークンと呼ばれる推測困難な文字列を生成します。

何かしらの情報をPOSTする際、HTMLでformタグを使用することになります。
このフォームに生成したトークンを非表示で埋め込みます。
Webアプリケーションにフォームの値が送信される際、このトークンも一緒に送信されます。生成したトークンとPOSTされるトークンが一致していればOKですし、NGであれば不正POSTと見なします。

下記コードが対策になります。

function setToken(){
    //変数tokenに推測困難なID(文字列)を高速に生成する
    $token = sha1(uniqid(mt_rand(), true));
    $_SESSION['token'] = $token;
}

function checkToken(){
    //セッションが空あるいは、POST時されたトークンと異なる場合
    if(empty($_SESSION['token']) || ($_SESSION['token'] != $_POST['token'])){
        echo "不正なPOSTが行われました";
        exit;
    }

    if($_SERVER['REQUEST_METHOD'] != 'POST'){
        //リクエストがPOSTでない場合
        setToken();
    }else{
        //リクエストがPOSTの場合
        checkToken();
}

以下、フォーム部分。

//非表示のフォームにトークンをセットする。

セッションハイジャック

ドットインストールさんでは、決まり事だと思って頂いてといいながら
下記コードを書いています。

session_regenerate_id(true);
$_SESSION['me'] = $me;
header('Location: http://example.com/index.php');

詳しくは調べてねという感じなので、これまた調べました。

セッションハイジャックとはなんぞや?

利用者がWebサービスにログインしたときにセッションIDを発行して、
以後ログインするときにセッションIDの情報をもとにログインする。
これをセッション管理などと呼ぶわけですが、
何らかの方法でネットワーク上でセッションが盗み見られたりする可能性があります。セッションIDがバレてしまうと乗っ取られて、なりすましでログインされてしまう可能性があります。
怖いですね。

対策は?

セッションIDが一度発行されてきり、ずっと同じIDを使用するのでは危険です。
セッションIDが攻撃者に入手されたらアウトですし、攻撃者がセッションIDを指定してユーザに使用させるということもできるようです。

つまり、同じセッションIDをずっと使っているのはよくないのです。

そのため、ログイン後に既存のセッションを破棄して、
新しいIDでセッションを開始するという手法が取られます。
ログインするたびに、常に新しいIDを使用するのです。

PHPでは、session_regenerate_id()関数を使用することで、
セッションIDを新しいものと置き換えることができます。
sesseion_regenerate_id(true);と引数をtrueとすることで、
古いセッション情報を削除することができます。(PHP5.1.0以降)

以上、ログイン処理時に考慮すべきセキュリティ対策の備忘でした。