値のサニタイズ
Webアプリケーションでは、フォームから入力された値を使って処理するのが基本です。ところがこのフォームというのは、どういう値が入力されるかわからない代物でもあります。例えば、数字を入力してもらいたいという場合でも、利用者は文字を送信してくるかもしれません。あるいは、悪意ある人間がサイトを攻撃する目的でおかしなデータを送りつけてくることもあるでしょう。そうしたことに対処するためには、「値の検証」について理解しておかなければいけません。
まずは、サイト構築を行う際、不可欠となる「サニタイズ」からです。サニタイズというのは、もともと「消毒」の意を持つ言葉です。転じて、送られてきたデータから「毒」を取り除く処理をこう呼ぶようになっています。
まずは、簡単な実験をしてみましょう。ごく単純なフォームを作成します。ざっと以下のようなものでよいでしょう。
<f:view>
<h:outputText value="JSF Page 1" id="text0"
style="color: #0000AA; font-size: 18px; font-weight: bold" />
<br /><br />
<h:outputText value="これは、JSFによる表示です。" id="text1"
binding="#{page1Bean.text1}" />
<h:form>
<h:inputText binding="#{page1Bean.field1}" />
<h:commandButton value="送信" action="#{page1Bean.button1_action}" />
</h:form>
</f:view>
このフォームから送信される管理Beanでは、ごく単純に、送られたテキストをそのまま表示するような処理を用意しておくことにします。入出力のコンポーネントを管理するフィールドとアクセサを含め、以下のような処理を用意しておけばよいでしょう。
private HtmlOutputText text1;
private HtmlInputText field1;
public HtmlOutputText getText1() {
return text1;
}
public void setText1(HtmlOutputText text1) {
this.text1 = text1;
}
public HtmlInputText getField1() {
return field1;
}
public void setField1(HtmlInputText field1) {
this.field1 = field1;
}
public String button1_action(){
text1.setValue("入力テキスト:" + field1.getValue());
return null;
}
これは、ごくごく基本的なフォームの処理ですね。ここでは何の処理もしていません。このままだと悪意あるスクリプトなどを送信されても対処できないことになります。例えば、以下のようなテキストを書き込んで送信してみましょう。
<script>alert('ok');</script>
スクリプトを送信すると、その場で実行できてしまう。 |
これを送信すると、画面にアラートが表示されます。送信されたスクリプトがその場で実行されていることがわかります。このスクリプトは無害なものですから実行されたところで問題はありませんが、例えば掲示板のようなところでJavaScriptを使ったスクリプトを投稿し、アクセスした人のクッキー情報を盗み出し、ユーザのパスワードを盗んだりすることもできてしまうのです。
こうした悪意ある送信への対処として行うのが、サニタイズです。サニタイズの基本的な考え方は、「出力される前に、データの中から悪意ある情報を取り除いたり無力化して表示する」というものです。この種のスクリプトの送信では、もっとも簡単な対処法は「タグを無効化する」ということでしょう。
これは、実は非常に簡単に行えます。結果を表示する<h:outputText>タグを、以下のように修正すればよいのです。
<h:outputText value="これは、JSFによる表示です。" id="text1"
binding="#{page1Bean.text1}" escape="true" />
タグの中に、escape="true"という属性を追加していますね。これで、このタグに設定される値は、すべてHTMLエスケープ処理されます。
スクリプトを送信すると、今度はそのままテキストとして表示され、スクリプトは実行されない。 |