このあたりの話題は、個々のプログラマに対して「気をつけろ」と注意喚起してもなくならない話題なのですが、
その背景的な部分をば少し。
サニタイズは消毒足り得ない
sanitize = 「無害にする」、という英単語ですが、≒ sanitate 「消毒する」と紹介されることが多いですね。
でも、この消毒という比喩は文学的ではあるけども、技術的には問題のある比喩に思います。
XSS(Cross Site Scripting、クロスサイトスクリプティング)への対処として言われることが多いですね。
現実の消毒というのは、過剰に繰り返しても問題はなく、
消毒済みのものをそのままもう一度消毒しても構わない。
なので、食品衛生的な現場では過剰なぐらいに「とりあえず消毒」というスタンスでやるわけです。
これに対しプログラム上やりたいことというのは
「その場の文脈でメタ文字となる文字をエスケープすること」
(
続・「サニタイズ言うなキャンペーン」とはより)なわけで、
例えば対HTMLでのエスケープ処理として"&"といった記号を"&"と置き換えたりするような処理です。
これは何度でも行える「消毒」ではなく、
正しい場所で一度きりしか実行してはいけない「変換処理」なんですよね。
しかし、プログラムにおけるエスケープは消毒とは違ってあくまで「変換処理」ですから、
正しい場所で一度だけ、しかも漏れなく行う必要がある。
そして、その場所というのが、「HTMLを出力する場所全て」という
どうやって網羅するんだよ、と言いたくなる広範な個所なのですね。
ハンガリアン記法
話は変わってハンガリアン記法。
Jittaさんの言う「型によるハンガリアン(システム ハンガリアン)使うな」の話です。
Wikipediaでも見てもらうと掴めると思うのですが、"iWindowHeight"みたいに、変数名の頭に型を表現する情報を
付加すると言う記法です。
この記法、Javaなどの強い型付けの言語の場合、プログラム上の「型」と変数名での「型」と冗長になるんですね。
そしてプログラムでの「型」はコンパイル動作で機械的にチェックされるので型の相違などは
検出・修正できるわけでバグとなっていつまでも残るようなことはないわけです。
そして、この冗長を常に保つことの難しさというのが欠点として挙げられていて、
メリットがないということが言われている。
ハンガリアン記法を保つためには、「全ての変数を宣言する箇所で」網羅的に命名を確認する必要があります。
そしてソースコードを修正する際に「型を変更する全てのケース」で網羅的に変数の命名も直さなくてはならない。
ヒューマンエラー
例えば、小学生低学年向けの、算数のドリルをやるとしましょう。算数の足し算を延々とやるわけです。
算数の足し算ぐらいは誰でもできますね。では、1万問のドリルで全問正解してください、と言われたら
「そんなの簡単だよ」と言えるでしょうか?
これは単純で簡単な作業であっても、人間はなんらかの間違いを犯すと言うことです。
「うっかりして」の「うっかり」なのです。
あなたがチームリーダーだとしましょう。10人のメンバー全員に1万問のドリルで全問正解させるにはどうしたらいいでしょうか?
この「うっかり」に対して「気合いを入れて」とか「集中して」とか精神論を掲げても、
確実性が上がるわけではありません。
俗にサニタイズと呼ばれる処理も、ハンガリアン記法も、原理を理解して対処することは難しくはない。
(いや、サニタイズ言うなキャンペーンはその原理の理解がされていないことを憂いてのキャンペーンだったか…)
算数ドリルのような話題です。ただし、その数がべらぼうで、「うっかり」間違えることもあるというものです。
10人分の計算ドリルをあなたが検算することで全問正解を目指すとしましょう。
あなたは検算を間違えないでやりとおせるでしょうか?
「うっかり」検算を間違えたりしないでしょうか?
XSSの話題というのはこの個々は簡単な作業なのだけども、
漏れなく実施しそれを保証するのが難しいというところが本題です。
そして一か所でも漏れがあるとそれでセキュリティホールになる可能性があるって言うんだから嫌になる。
ハンガリアンでもやはりきっちりと網羅して行うことの難しさというのがあって運用に堪えない。
こうした部分にはヒューマンエラーがするりと入り込んでくるので頭が痛い問題です。
アスペクト指向というパラダイム
拙稿アスペクト指向の概念
でおおむね解説しているわけですが、アスペクト指向では「全てのXXに全部YYをする」という事象を扱います。
これをアスペクト、「横断的関心事」と呼ぶわけです。
上記、挙げてきた件を解決しようという試みなわけですね。
このアスペクト指向というのはOOP(オブジェクト指向プログラミング)の
概念とぶつかるものではなく、相補的なものと言えます。
AOP(アスペクト指向プログラミング)に対応した言語では、関数のようなものを作って、
この処理を「全てのXX」に差し挟む、ということが記述できます。
この「全てのXX」という部分にOOPでのオブジェクトなどが用いられたりするわけです。
また、AOP対応言語でなくとも、設計のパラダイムとしてのアスペクト指向というのはあって、
OOPでのデザインパターンでProxyパターンというものがありますが、これは、
Proxyするオブジェクトで前後に処理を一律に差し挟むことを可能とする。
アスペクト指向的な概念に対してOOPの枠内でできる対処法のひとつなんですね。
XSSに代表されるように、横断的関心事というのは人間の手作業では
ヒューマンエラーとも密接に関わって非常に対処しにくい。
AOPはプログラミングのパラダイムとしてだけではなく、開発体制をいかに構築するか
(私はこれをシステムを構築するプログラミングの仕事と類似する事項と思っています)
という部分にも応用することができる。
日常の開発の中で、こうしたアスペクトを捉えて、それを一網打尽にするジョインポイントはどこか、
そう考えると見えてくるものがいろいろあるのです。
投稿日時 : 2008年7月6日 18:34