カテゴリー: Secure Coding

プログラミングの「世界観」

rustcを通らないコードは間違っているに以下のような記述があります。

「そのコードがRust wayではない」という点で「間違っている」。microなスタイルからmacroな設計まで、ありとあらゆる点でRust的なコードであることを暗黙的ではあるが極めて強く要求する。それがRustというプログラミング言語だ。

Rustはコンパイル時点で可能な限りの正しく実行できないコードが生成されないような言語になっていることは比較的良く知られていると思います。このブログはこの違いを「世界観」が異なるという視点でまとめています。

Rustの場合、マルチスレッドプログラミングでデータ競合が起きないような書き方をしなければならない制約があり、従来のプログラミング言語とは異なる考え方(=世界観)が要求されている。自分のコードは正しくても「Rustの世界観では間違っている」としています。

「世界観」の違いで言語やプログラミング方式を捉える考え方は面白いと思います。

もっと読む

覚えるパスワードの作り方

覚えなくて構わないパスワード(ブラウザなどのパスワードマネージャーに記憶させる最強のパスワード)の作り方は、

覚えないパスワードは生成する物 〜 余計な文字数制限などは有害 〜

で紹介しました。最強のパスワードを自分で作るのが面倒な方はこのページのランダム文字列から90文字くらいをコピー&ペーストして使ってください。

今回は覚えられる最強のパスワードの作り方です。

備考:あるニュース記事で”ブラウザのパスワード機能は使わない”とする記事がありました。その理由は、離席した場合などにパスワードが表示できる物もあるから、でした。しかし、PCをログインしたままロックもせずに離席すると、ログイン済みならアクセス仕放題、サードパーティー製のパスワードマネージャーを使っていても利用するサービスにはログイン仕放題、です。デバイスの物理セキュリティは何をしていてもある程度は使い方で保証しなければセキュリティは維持できません。

もっと読む

”形式的検証”と”組み合わせ爆発”から学ぶ入力バリデーション

形式的検証とは

形式的検証(けいしきてきけんしょう)とは、ハードウェアおよびソフトウェアのシステムにおいて形式手法数学を利用し、何らかの形式仕様記述やプロパティに照らしてシステムが正しいことを証明したり、逆に正しくないことを証明することである

英語ではFormal Verificationとされ

formal verification is the act of proving or disproving the correctness of intended algorithms underlying a system with respect to a certain formal specification or property, using formal methods of mathematics.

と説明されています。形式手法として紹介されることも多いです。

参考: 形式検証入門 (PDF)

形式的検証は、記述として検証する方法から数学的にプログラムが正しく実行されることを検証する仕組みまで含みます。数学的な形式的検証では、可能な限り、全ての状態を検証できるようにしてプログラムが正しく実行できることの証明を試みます。

参考:ソフトウエアは硬い (日経XTECHの記事)

契約プログラミング(契約による設計 – Design by Contract, DbC)も形式的検証の1つの方法です。

形式検証の仕組みを知ると、厳格な入力バリデーションが無いと”組み合わせ爆発”により、誤作動(≒ セキュリティ問題)の確率も爆発的に増えることが解ります。

もっと読む

X-Content-Type-Options: nosniff はIE以外にも必要

往年のWeb開発者であれば X-Content-Type-Options: nosniff はIE専用のオプションHTTPヘッダーだと理解している方が多いと思います。

この理解は正しかったのですが、現在は正しくありません。nosniffはChromeやFirefoxの動作にも影響与えます。このため、IEをサポートしないサイトであっても X-Content-Type-Options: nosniff は必要なHTTPヘッダーです。

もっと読む

SQLクエリと識別子エスケープの話

Facebookでこんなやり取りをしました。元々公開設定で投稿した物で、議論させて頂いた浅川さんにも「ブログOK」と許可も頂いたので、そのやり取りの部分だけを紹介します。

テーマは「SQLクエリと識別子エスケープ」です。

とあるブログの結論として

“「安全な静的SQLの発行方法」を開発者に啓蒙すればいいだけだ。つまり

  • プリペアドクエリでSQL発行は行うこと
    この場合変数のバインドは必ずプレースホルダを用いること。

SQL文の文字列操作は禁止であり、これほどシンプルなことも無いだろう”

と書かれていました。しかし、私はこの意見に対して

実践的なSQLクエリを書いたことが全くない開発者なのでしょう??
ソートカラム、抽出カラムを指定するSQLクエリでは「識別子(カラム名)が変数」になります。
初歩的なSQLクエリですが”自分が書いたことないから”といって一般的ではないと勘違いしています。行のソート順、抽出カラムを指定するSQLクエリは業務アプリでは”一般的”です。当たり前ですが。

こうやってベストプラクティスもどきのアンチプラクティスが使われて、喜ぶのはサイバー犯罪者とセキュリティ業者だけですよ。

とコメントしました。SQLのテーブルやジョイン結果を「表」として表示した際に、任意のカラムのソート順を指定するUIは、自分で作ったことが無かったとしても、ごく一般的だと分かると思うのですが・・・

もっと読む

Computer Programming Fundamentals and Principles – Input Validation


I had discussion on PHP dev mailing list. It appeared that not few developers misunderstand “What is Input Validations“. Therefore, I summarize computer programming fundamentals and basics to help understanding validations.

Without fundamentals and basics understanding, discussion is meaningless. “Input Validation” is one of the most important countermeasure for cyber attacks. The idea is strongly supported by notable computer scientists (e.g. CMU’s CERT) and security specialists, yet it is misunderstood by majority of developers. Therefore, almost all web applications are missed to have proper “Input Validation” currently.

I came across this discussion too often, so I summarize why, “Input Validation”, “Input Data Validation” or “Application Input Data Validation” especially, is fundamental and mandatory requirement for applications.

TL;DR;

“Application Input Data Validation” and “Business Logic Validation” are 2 different validations by fundamentals and principles. Except few exceptions, ALL web application input data can be validated by “Application Input Data Validation” without user interactions. This achieves more secure state and cleaner/manageable code structure. Thus, applications should implement “Application Input Data Validation” always.

Note: “Application Input Data Validation” is NOT a replacement of “Business Logic Validation”.

もっと読む

「脆弱性を局所的に潰す」はアンチプラクティス

本物の「セキュアコーディング」(セキュアプログラミング)を知ればもう議論など必要ない、と思っています。本物の「セキュアコーディング」を「知ろうとしない」と幾らでもアンチプラクティスを作ってしまいます。

議論は終り、と思っていたのですがそうも行かないようなので紹介します。セキュアコーディングの概念を全く知ろうとしないで、セキュリティを作るのは「ただの無駄」です。多数のアンチプラクティス/間違いが含まれるスライドの中から(一々指摘するとキリがない)

  • 「脆弱性を局所的に潰す」

これ”だけ”だとアンチプラクティスです。

※ 契約プログラミングが流行らない理由はこいうアンチプラクティスも原因でしょう。特定の良いこと”だけ”を積み重ねても良い結果にならない、ことは合成の誤謬として知られています。

もっと読む

エンジニアなら理解る文字エンコーディングバリデーションの必要性

入力バリデーションで文字列の妥当性を検証(保証)しないと、不正文字問題の解決はできません。

よく「文字エンコーディングバリデーションは入力バリデーションしなければならない」と紹介はするのですが、その理由を詳しく解説していませんでした。これは文字エンコーディング攻撃の仕組みを理解してれば分かる事なのでしていませんでした。

しかし、文字エンコーディング攻撃の仕組みを理解していても必要なし、とする意見があるので理解り易く説明します。(理解りづらかったら教えてください)UTF-8のみですが、他の文字エンコーディングでも基本は同じです。

もっと読む

バリデーションですべきこと

このブログは、IPAは基礎的誤りを明示し、正しい原則を開発者に啓蒙すべき、の「追加の情報」として書いた物を別エントリとしてまとめた物です。

CERTセキュアコーディング

  • 入力バリデーション(原則1)
  • ”セキュアコーディング標準”による安全なロジック処理(+具体的な入力/出力処理)※ 原則10 「セキュアコーディング標準を採用する」=自ら作るモノ
  • 出力の無害化(原則7)※ IPA版は原則2

の3つが1つのセットとして成り立ちます。これ以外はセキュアコーディングではありません。

入力、ロジック、出力、これら全てにバリデーションが必要です。

参考: コンピュータは数値さえ正確に扱えない

もっと読む

IPAは基礎的誤りを明示し、正しい原則を開発者に啓蒙すべき

セキュアコーディングの第1原則は「入力をバリデーションする」です。セキュアコーディングの第1原則はソフトウェアセキュリティの一丁目一番地と言えるセキュリティ対策です。

入力バリデーションを第一のセキュリティ対策としているガイドライン:

セキュアプログラミング/セキュアコーディングを要求するセキュリティ認証:

  • ISMS – 国際情報セキュリティ標準 ISO 27000 の認証規格
  • PCI DSS – クレジットカード情報を取り扱う場合の認証規格

90年代初めからコンピューターサイエンティストのセキュリティ専門家は「入力バリデーション」が重要であるとしてきました。「入力バリデーション」は論理的にセキュアな構造のソフトウェアを作る為に欠かせない必須の要素だからです。防御的プログラミングから数えると四半世紀を越える月日が経っています。

しかし、残念ながらセキュアコーディングの第1原則の「入力バリデーション」は普及しているとは全く言えません。この状況には理由があります。

この状況に責任があるIPAは、IPAのセキュアプログラミング講座 1に基礎的な誤りがあったことを明示し、開発者に与えた誤解が正されるよう、最大限の努力をすべきでしょう。

IPAのあり得ないような基礎的誤りがどのような物だったか、ご覧ください。

追記: IPAは問題のページを更新/削除したようです。

もっと読む

ベストプラクティスもどきのアンチプラクティス TOP 10

ここ十数年で見聞きした、脆弱なアプリを作ってきたベストプラクティスもどきのアンチプラクティス、をリストアップしてみます。

限定された条件ではベストプラクティスと言える物でも、一般化するとアンチプラクティスになる物は多いです。

コード検査をしていると良く分るのですが、アンチプラクティスは強力な破壊力を持っています。ここに書いているアンチプラクティスを無くすだけでも、致命的な問題/脆弱なコードを多数無くすことができるでしょう。

特徴として原理や原則、適切な構造に合致しない物がアンチプラクティスになっています。

  • 原理:コンピュータープログラムは妥当な入力でしか、正しく動作しない
  • 原則:Fail Fast原則、失敗するモノはできる限り早く失敗させる、が守られていない
  • 構造:セキュリティ対策では境界防御、それも最外周の防御、が欠かせないがアプリケーション境界の防御が不十分・不適切

TOP 10と題しましたが、アンチプラクティスの順序と重要性(悪影響)にはあまり関連性はありません。

もっと読む

プログラムから「想定外」を無くす方法

ほとんどセキュリティ問題は「想定外の動作」が原因です。例えば、インジェクション攻撃は開発者にとって「想定外の動作」でしょう。ソフトウェア開発者が意図しない想定外の動作のほとんどは「想定外のデータ」が原因です。

この事実をから簡単に分かる「想定外」を無くす方法があります。たった2つの方法を”両方”行うだけで、現在あるアプリの9割程度の脆弱性が無くなります。

今まで出来る限り正確に「どうすれば想定外をなくせるか?」を紹介してきましたが、今回は出来る限り簡潔にどうすると良いのか、ダメなのか紹介したいと思います。 もっと読む

セキュリティを論理的に構築する方法

セキュリティの原理、原則、ベストプラクティスに自分でコメントを追加しました。以前、論理的にセキュリティ対策を検証する方法論理的なセキュリティ対策の評価方法は書いたのですが、論理的にセキュリティを構築する方法は書いていないことを思い出しました。追加したコメント欠陥だらけのソフトウェアセキュリティ構造を紹介したブログをベースにセキュリティを論理的に構築する方法を紹介します。

このエントリの解説はCERT、つまり米カーネギーメロン大学、の資料をベースにしています。

もっと読む

セキュリティの原理、原則、ベストプラクティス

「セキュリティの」と付けていますが、どの分野でも共通することだと思います。

何事でも論理的に何かのガイドライン/ルールを作る場合、まず変えることのできない

  • 原理 – 事物・事象が依拠する根本法則

を見つけ、その原理から導き出される

  • 原則 – 多くの場合に共通に適用される基本的なきまり・法則

を作り、さらに特定の条件下の具体的な事例として

を作ります。原理、原則、ベストプラクティスを理解していないと様々な問題がおきます。これらの基本的関係は

原理 > 原則 > ベストプラクティス

です。しかし、適用範囲の広さは

原理 < 原則 < ベストプラクティス

です。例えば、ベストプラクティスは”例外的”に原則に反した方法が”最善の方法”となる場合も少なくないからです。よく混乱や誤解の元になりますが、条件を絞った場合(例外的なケース)のベストプラクティスも在ります。

例外的なケース(一般的で無いモノ=例外的な物)をベストプラクティスにすることには異論もありますが、結構狭い条件でしかベストプラクティスにならないモノが”ベストプラクティス”と呼ばれていることは多いです。1

もっと読む