Yabu.log

ITなどの雑記

WEBアプリではどのようにセキュアな値を管理すべきか

かなり初歩的な内容。この程度のことがわからず非常に悔しい思いをしました。 適当に本や調べて学んだことをまとめます。もうちょっと書き足したり、内容を大幅に変更してQiitaに投稿するかもしれません。

URLパラメータ(GET)

普通にURLをクリックしたり、formのmethod属性を指定しないかGETを指定する。

例えばGoogle検索のformはこんな感じになっている

<form class="tsf" action="/search" style="overflow:visible"
      id="tsf" method="GET" name="f" onsubmit="return q.value!=''" role="search">

submitすればgetリクエストとしてform中のinput要素の内容がurlパラメータとして送信される

get: HTTP GET メソッドに相当します。フォームのデータは '?' をセパレーターとして action 属性の URI に追加して、その結果となる URI をサーバにー送信します。フォームが ASCII 文字列だけを含み、まったく副作用がない場合にのみ、このメソッドを使用してください。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/form#attr-method

URIは仕様上長さ制限はないが、IEでは上限が2038になっていたり*1、古いブラウザでは255文字まで扱えなかった*2などの例がある。この場合は後述のPOSTを使う。

URLパラメータを含んだURLはブックマーク可能

このurlはgoogleのhelloworldの検索結果だが、こちらをブックマークしたり、用意したURLを他人に踏ませることは可能。

https://www.google.co.jp/search?q=helloworld

またユーザーが任意にパラメータを指定可能であるから、ここに権限のフラグや料金や所持金額などを格納してはいけない。

getのリクエストはログに残る

アクセスログなどからURLの内容が外部に流出する恐れがある。 httpsを利用していない場合、経路間で盗聴される恐れもある。

だから基本的に漏れてはいけない・改竄されてはいけない情報をURLパラメータで扱うべきではない。

ユーザーIDをURLパラメータで指定できるシステムで、クライアント側でユーザーIDを弄られて、 他のユーザーの個人情報が漏れるのはセキュリティ事故あるあるらしい。

POST

getを使わない方法としてPOSTがある。formのaction属性をpostにしてformの中のinputの値をリクエストボディに含めて送信する。この場合、getと違ってurlパラメータには値は乗らない。当たり前だけど一般的にログインとか決済みたいなアクションはPOSTで行われている

hidden項目のinput

hidden項目はクライアント側で書き換え可能

任意のHTTPリクエストを組み立てるような高機能のツールを使わなくても、各ブラウザの開発者モードの画面で簡単に書き換えることができる。 だから ここに権限のフラグや料金や所持金額などを格納してはいけない。(大事なことなので2回書きました)

hidden項目の使い道は?

  • CRSF対策のトークンの格納
  • 他のinput以外でサーバーに渡したい値のうち、見せる必要のないもの

ショッピングサイトなどでは「カートに入れる」ボタンを押した際に何をカートに入れるか?をhiddenで持っていることが多いらしい。 例えばAmazonではASIN*3*4をhidden項目として画面側に持っている。

cookie

後述のセッション変数と違い、セッションが終了しても値が破棄されない。*5

  • セッションIDの格納
  • 自動ログインのためのトーク
  • アクセス解析のための情報
  • 広告のための追跡情報

などを格納する set-cookieフィールドに格納されているのでhttpsを利用していない場合経路で漏れる可能性がある。 またhttp-only属性が付いていないものに関してはクライアント側で書き換えできるので、ここに権限のフラグや料金や所持金額などを格納してはいけない。(大事なことなので3回ry)

session変数

session idをキーにサーバー側で値を保持するセッション変数という仕組みがある。 一般的にsession idはcookieに格納し、第3者に分からないようにする。具体的には

  • 漏洩
  • 推測
  • 第3者による固定化の強制

を防ぐ。

isAdiminのような特権的な扱いをする情報はここに持たせるべき。

雑感

色々書いたけど、最近はフレームワーク側で色々やってくれるので セキュアな部分は自分で作らずにそちらを利用するのがいいと思う。

まぁそんな心持ちでやってるから、いざという時何もできなかったのですが。

参考

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

http://www.designmap.info/homepage/homepage/html_xhtml/input-hidden/ https://developer.mozilla.org/ja/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data https://www.ipa.go.jp/security/awareness/vendor/programmingv1/a01_04.html http://hogem.hatenablog.com/entry/20100307/1267977441

*1:WEBを支える技術4.5URLの長さ制限

*2:プロになるためのWEB技術入門

*3:Amazonグループが取り扱う、書籍以外の商品を識別する10桁の固有番号

*4:https://www.amazon.co.jp/gp/seller/asin-upc-isbn-info.html

*5:期限は設定可能