スライド "Rails4 Security" 論争のまとめと、職業的倫理感の話

大垣靖男さんのスライド "Rails4 Security" にまつわる議論がややこしくなってきたので、ちょっと整理してみました。複数の議論が並行して融合しつつ分離しつつ進行しているので自分自身よくわからなくなってきているので。

 

時系列

議論のトピック1: 何故インターネットで広まる前に止められなかったのか

これは技術的な話ではないので飛ばして読んでもかまいません。

"Rails4 Security" は岡山Ruby会議02で招待講演として発表されたものです。私は現地にいなかったのですが、岡山Ruby会議02 まとめ #okark02 - Togetter を見る限りツッコミはとくになく、フムフムなるほど、という感じの反応が多かったようです。

スライドは直後に slideshare へアップロードされました。何を思ったのか FacebookRails 技術者認定試験運営委員会の公式ページが

Rails技術者認定試験運営委員会が参加しているBOSS-CON JAPAN 理事の大垣靖男氏が、岡山Ruby会議02で「Rials4 Security」を講演しました。

資料が以下よりダウンロードできるそうですので、興味がある方は是非!

とシェアしました。

シェアする前に問題を感じなかったのでしょうか。

そして「いいね!」を11件集めてしまいました。

いいのか。

この段階でさすがに誰かからツッコミが入ったのでしょうか、

その資料についてコメントをいただいたので、大垣氏の回答をFacebookにアップいただきました。ご参考までご連絡いたします

と運営委員会ページに更新がありました。

が、結局のところ現時点では運営委員会にたいして「いいね!」が19件、大垣さんの「コメント」に対して「いいね!」12件、シェア1件。そんなに多くはないのですが、さすがにこれはどうよと思いました。

もっと早くなんとかならなかったのか、と思いました。

しかしここは私の力の及ぶところではないので、問題提起にとどめておきたいと思います。

議論のトピック2: Strong Parameter論争

Strong Parameters は値の中身までチェックするのかしないのか、という議論です。スライドでは「する」ように読めてしまいます。というか、そう読むほうが普通でしょう。

結論を言えば、Strong Parameter は「値の中身をチェックしません」。そんな機能じゃないです。単に Mass Assignment 対策にすぎません。

この点について私が指摘した記事がこちらです。

あとから気づいたのですが、この件はバリデーションの定義に関係ありません。そんな機能ねーよ、という単純な話です。後述のトピック3. と分離して話すべきだったな、と思います。もうちょっと上手に説明できたかもしれないな、と今は反省しています。

 

議論のトピック3: バリデーション論争

Strong Parameters の役割がバリデーションの一部に含まれるのか否か。そもそもバリデーションとは何なのか。バリデーションはセキュリティのためのものなのか、といった、セキュリティにまつわる話です。過去の蒸し返しを含む広い議論です。

 

議論のトピック4: 職業的倫理の話

これも技術的な話ではありません。

大垣さんの態度が技術者の職業的倫理上、正しいものなのかどうか、というところを私は疑問に思いました。大垣さんは私の指摘に対して、論点のすりかえ・わら人形攻撃・架空の論点の設定・私に対する印象の操作といった、数々の詭弁術を用いて反応しました。Facebook での議論を引用します。

山崎良祐(=本エントリの筆者。以下「私」):

初めまして。Rails 4 に Strong Parameters にバリデーションに相当する機能はありませんので「Rails 4 のバリデーションは Controller」とおっしゃる点については根本的に間違いかと思います。Rails 4 の仕様について、いまいちどご確認いただきたく思います。

 

大垣さん:

バリデーションに相当する機能が無い、の意味が分かりません。プログラムで言うバリデーションとは「データの妥当性を検証する事」を言います。validate*という名前が付いているからバリデーションと呼ぶ物ではありません。

「根本的に間違い」との指摘内容に対して大垣さんは「意味がわかりません」と一蹴しました。

また私の「Strong Parameters にバリデーションに相当する機能はない」という指摘を歪め、あたかも私が「Strong Parameters を用いる必要はない、validate* ですべて代替すべき」ないしは「validate* はバリデーションでないと大垣さんが言っている」と主張したかのように「validate*という名前が付いているからバリデーションと呼ぶ物ではありません」と反論をしました(わら人形攻撃)。

次。

私:

Strong Parameters は検証するものではなく更新可能なパラメータのみを通すというもので、いわばフィルタであり、既存の validates* を代替するものではありません。Rails 4 でも Rails 3 以前と同様、Model での validates* を用いた値の検証が必要です。スライドでは「Rails 4 のバリデーションは Controller、Rails 3 のバリデーションは Model」とあり、あたかも validates* の機能を strong parameters が代替するか、validates* 相当を Controller で実装することが求められるようになったかような誤解を招きかねませんので、その点をご指摘申し上げた次第です。

 

「validate*という名前が付いているからバリデーションと呼ぶ物ではありません。」との点について、根本的な認識の確認なのですが、validates* は値の妥当性検査の役割を担わない、あるいは validates* が値の妥当性検査の役割を果たすに不適格な存在であるとの認識でしょうか?

 

大垣さん: 

バリデーション(データの妥当性検証)はどこで行なってもバリデーションです。Modelでのバリデーションも否定していません。多層防御を行う事はベストプラクティスですが、入力したデータが未検証のまま利用される可能性(ActiveRecord以外のコードの事を言っています)を残す、モデルのみのバリデーションはバッドプラクティスである、と言う事です。セキュリティのベストプラクティスとして「不要なパラメータ」の検出は必要ですが、Rails4では検出しようとはせず無視(デフォルトではログだけ)していますね。更新可能なパラメータをバリデーションし、残りは無視する動作はフィルタですが、paramsに対して行う事はバリデーションです。この動作が設計上の問題であることは機会があれば触れたいと思います。

大垣さんは引き続き架空の指摘に対する反論を繰り広げました。

【実施する場所によってバリデーションか否かが決まる】と私が主張したかのように「バリデーション(データの妥当性検証)はどこで行なってもバリデーションです」と反論し、【大垣さんがModelでのバリデーションを否定している】と私が主張したかのように「Modelでのバリデーションも否定していません」と反論しました(わら人形攻撃)。どちらも私からの「validates* は値の妥当性検査の役割を担わない、あるいは validates* が値の妥当性検査の役割を果たすに不適格な存在であるとの認識でしょうか?」との質問の回答になっていません。

次に、大垣さんは「多層防御を行う事はベストプラクティスですが〜」と語りはじめています。私は多重防御の必要性や Controller 層での値の妥当性検証の必要性の有無を議論の俎上に挙げていませんので、ここでは大垣さんは議論の中心でない問題を語っていることになります (=複製ニシンの虚偽)。

【Strong Parameters はそんな機能もってない、スライドの表現はおかしい】との私の指摘に対しては「設計上の問題である」と反論しました (論点のすりかえ)。

次。 

私:

なるほど意図は理解しました。のちほどよく考えてみたいと思います。(※注: バリデーション論争をする気はなかったので流しました)

それはさておき、validates* の機能を strong parameters が代替するか、validates* 相当を Controller で実装することが求められるようになったかような誤解を招きかねない件について、急ぎ対応をお願いできませんでしょうか? Twitter上でそのような誤解をされている方をみつけました(ユーザ名はさしひかえます)ので、誤解が広がらないようにするためにスライド作者である大垣様から何らかのアクションをお願いしたいと思います。

 

大垣さん: 

よくRailsのコードを見てみないと勘違いしているかも知れませんが、恐らくStrong Parametersの問題はpermitsを制御する数行のメソッドを追加するだけで解決すると思います。APIに制限があるのは当たり前、とスライドにも書いていますがStrong Parametersの制限について触れておく必要はありそうです。近々、解説を入れたいと思います。(今週末になると思いますが、、)

「よくRailsのコードを見ていないと勘違いしているかも知れませんが」と、私が Rails のコードを読んでいないかのような可能性をほのめかしました (実際はけっこう読んでいるつもり)。これは第三者からみた私に対する印象に影響するものですから、かなり悪質です。

また「Strong Parametersの制限」なる(存在しない、これまで議論の俎上にすら上がっていない)ものを持ち出し「APIに制限があるのは当たり前、とスライドにも書いていますが」と宣言しました。それで何が正しいのか証明されているのかは不明ですが。

 

以上のように、私からの指摘は詭弁術で何度となくかわされてしまいました。

論理的な正しさはさておき、意識的なものかどうかもさておき、このように詭弁を繰り広げることは技術者の職業的倫理感に照らし合わせて果たして正しいことなのでしょうか?

私は建設的な結果をもたらさず、害悪としかならないように思います。誤った認識を改めるのを妨げますし、その誤った認識をまき散らすことになりかねません。ですから、少なくとも私の倫理観とは相容れません。

もちろん自分が聖人君子だと言うつもりはないです。詭弁、多少ならば私もやらかしますし、やられた同僚にはそのたびに申し訳ないとおもいます(申し訳ありません、とこの場で言っておきます)……けどね、大垣さん、今回はほとんど全部が詭弁じゃないですか。Facebook のコメントを強制的に削除したりブロックしたりはしなかったので某市市長によりも敬意は持てますが、ちょっとあんまりにもあんまりです。