ユーザーに改変してほしくない処理をJavaScriptで書いてしまうことは、とても危険です。なぜ危険で、どれほどクリティカルな問題なのかということを書いていきたいと思います。
##ユーザーを信用してはいけない
まず、大前提としてプログラミングの世界ではユーザーから入力されるデータや送られてくるデータを信用してはいけません。もちろん大半のユーザーは悪さをしようとは考えていないと思いますが、中には悪さをしようとするユーザーもいます。そんなユーザーが悪意のあるスクリプトを送ってきたり(XSS)、SQLインジェクションなどで攻撃してきたりした時に、何も対策をしていないとデータを改変させられたり、抜き取られたりしてしまう危険があります。対策としては、エスケープ処理をしたりプリペアードステートメントを利用したりすればいいのですが、今回はXSSなどの対策の話ではないので割愛させて頂きます。
##入力フォームからの入力だけ注意すればいいわけではない
入力フォームの値はエスケープ処理などをしてサニタイズしていたとしても、JavaScriptのコードに脆弱性があったりするとそこから攻撃されてしまう危険があります。基本的に改変されたくないコードをJavaScriptのコードに書いてはいけません。なぜならJavaScriptのコードはクライアントサイドで書き換え可能だからです。デベロッパーツールなどを使えば任意で書いたコードを実行させることが簡単にできてしまいます。
##実際にデベロッパーツールからスクリプトを実行させてみる
実際にGoogle Chromeのデベロッパーツールを利用してスクリプトを作成してみましょう。
###アラート表示
これだけで、任意のスクリプトを実行させることができてしまいます。
###jsファイルの改変
jsファイルの書き換えの場合は、Sourcesという項目からファイルを選択して書き換えることができます。クリックイベントなどの箇所を書き換えたい場合は、下記のように要素を選択してからEvent Listenersという項目を選んでjsファイルをクリックすれば、クリック処理の箇所に飛ぶことができます。(すごく便利)
クリック処理の箇所に飛んだ後に、既存の処理を書き換えてCommand + S(Macの場合)かCtrl + S(Windowsの場合)で保存すれば処理を改変させることができます。
上記のように、jsの処理は難読化などがされていなければ簡単に書き換えることができてしまいます。
##脆弱性のあるプログラムの例
記事評価をさせるためにいいねボタン
や役に立ったボタン
などを用意して、評価された数を表示するようなものがあった場合を例にあげてみます。
- ページの
いいねボタン
を押した際にajax(記事IDや評価の累計数をjsから送る)でサーバと非同期通信。 - サーバサイドでjsから送られたデータを元にDB情報を更新(評価数もjsから送られた累計数を元に更新)。
- 正常に更新処理が行われたことをjsで受け取り、現状のページに表示されている評価数をインクリメントして表示する処理をjsで行う。
上記のような処理があった場合、これはクリティカルな問題があります。ポイントは、**評価数の累計もjsから送られてきた値を元にしてしまっているところです。**これでは、jsで送る値を改変してしまえば評価数を0にすることなどができてしまいます。
##まとめ
基本、クライアントサイドの処理は簡単に改変できてしまいますので、ユーザーに改変してほしくない処理をクライアントサイドで行うことはとても危険です。そういった処理はサーバサイドに書くようにしないといけないと思います。ちなみに、Cookie
なんかも簡単に書き換えられますので、改変してほしくない値は保持させないようにしましょう。重要なことは**ユーザーには悪人がいるかもしれないということを常に忘れずにプログラムを書いていくことだと思います。**逆に世の中の人がみんな善人ならクライアントサイドに書いても別に問題ないんですけどね(笑)。
##参考