任意のテキストをURLで使えるように変換してリンクを作成するって言う作業をしてて、どの文字を許可すれば安全かわからなかったので色々調べてみたわけだが。手抜き検索して出てきた情報を鵜呑みにしたらはまった。

情報はこんなの。

以下の文字はURLに使えないそうです。

\"'|*`^><)(}{][

実際には、#でも%でもポストエラーが出るし、'や()は使える。
ていうか、そもそも使用目的があって初めてその目的でこの文字が使えるかどうかが決まるわけなので、「使える」「使えない」で出てきた情報がそのまま役に立つわけないじゃんね。迂闊でした。
想定している使用方法は、Amazonの商品ページのようにURL内に商品名を含めるというもの。例えばこんな感じ。

http://www.example.com/こんにちは!こんにちは!/product/000123


RFCを読んだわけではないけれども、それに基づいた資料で判断した結果が以下。

1. URLに記述することが出来ない
<>"{}|\^[]`
2. URLに記述すると特別な意味を持つ
#%;/?:@&=+$,
3. 記述できるけどやめておいた方が良さそうな文字
'()

こんな感じですか。

1についてはまぁわかるんだけど、2がちょっとうっかりしてた。URLの途中で#が入っていれば当然そこでURLは終わりその後は部分識別子ってことになるし、%が入っていればその次の2文字はURLエンコードされた文字ってことになるから16進数([0-9A-Fa-f])でなくちゃいけないし。

3については実際問題別に問題なく動くんだけども、XSS的にみてなんか怖いのでやめておく。自由入力なわけじゃないので問題のあるURLが実際に使われてしまうってことはないんだけどもね。入力者を信用しても仕方がないので。


というわけでこれらの文字は全て削除し、スペースはハイフンに変換。その上でURLエンコード。

コレで大丈夫、だと思うんだけどなぁ…