この記事では、プログラムの安全の基本について、肩の力を抜いて学んでいきましょう!
自分の書いたプログラムが、ある日突然、悪い人に狙われたら…なんて考えたこと、ありますか? ちょっと怖いですよね。でも大丈夫! この記事を読めば、プログラムをガッチリ守るための第一歩、セキュアコーディングの考え方が身につきます。
セキュリティって聞くと難しそう…と感じるかもしれませんが、ここでは難しい話は抜きにして、プログラム作りを楽しむ皆さんが、安心して開発を進められるような、そんなお話をしていきますよ!
この記事を読むと、こんなことがわかります
- なぜプログラムの安全性が求められるのか
- セキュアコーディングの基本的な考え方
- 初心者がまず押さえるべきセキュリティ対策のテクニック
- 安全なプログラム作りを続けるためのヒント
なぜプログラムの安全は基本なのか?セキュアコーディングの重要性
それは、プログラムが私たちの生活に欠かせないものになったからです。ショッピングサイト、SNS、銀行のシステム…身の回りはプログラムだらけ。もし、これらのプログラムに弱点、専門用語でいう脆弱性(ぜいじゃくせい)があったらどうなるでしょう?
想像してみてください。
- ショッピングサイトから、あなたの名前や住所、クレジットカード情報がごっそり盗まれる…
- 会社のシステムが止まってしまい、仕事ができなくなる…
- SNSアカウントが乗っ取られて、変な投稿をされる…
考えただけでもゾッとしますよね。プログラムの安全を怠ることは、利用者や会社に大きな迷惑をかけるだけでなく、作ったあなたの信頼も失うことにつながりかねません。
だから、プログラムを作る人は、機能やデザインと同じくらい、「安全であること」を基本として考える必要があるんです。セキュアコーディングは、特別な人だけがやるものではなく、プログラム開発に関わるすべての人が身につけるべき、いわば基礎体力のようなものなのです。
プログラムの安全を守るセキュアコーディングの基本原則
じゃあ、具体的にどうすればプログラムは安全になるんでしょうか?
魔法のような一発解決の方法はありませんが、昔から「これを守っておけば、かなり安全になるぞ」と言われている基本的な考え方、つまりセキュアコーディングの基本原則があります。
ここでは、特に覚えておきたい3つの原則を見ていきましょう。
原則1:入力値は常に疑うバリデーションの基本
プログラムは、ユーザーが入力した文字や、他のシステムから送られてきたデータなど、外部からの「入力値」を受け取って動くことがよくあります。
このとき、「送られてくるデータは、いつも正しいとは限らないぞ!」と疑ってかかるのが基本です。悪意のある人が、わざと変なデータや攻撃用のコードを送りつけてくるかもしれません。
そこで行うのがバリデーション(検証)です。
- 数字を入れてほしいところに、文字が入っていないか? (型チェック)
- メールアドレスの形式になっているか? (形式チェック)
- パスワードは短すぎないか? (長さチェック)
- ありえない年齢(例 200歳)が入力されていないか? (範囲チェック)
こんな風に、受け取ったデータが想定通りか、変なものじゃないかをしっかりチェックします。
面倒くさい? いえいえ、この一手間が、予期せぬエラーや攻撃からプログラムを守る盾になるんです。入力値のチェックはセキュアコーディングの入り口と言っても過言ではありません。
原則2:出力するデータは無害化するエスケープ処理
プログラムが処理した結果を、画面に表示したり、ファイルに書き出したりすることも多いですよね。
この「出力」のときにも注意が必要です。特にWebアプリケーションで、ユーザーが入力した内容をそのまま画面に表示するような場合、そこに悪意のあるスクリプト(プログラムの命令)が仕込まれていると大変!
例えば、誰かがコメント欄に
<script>alert('罠だよ!');</script>みたいな文字を入力したとします。これをそのまま画面に表示してしまうと、そのページを見た他の人のブラウザで、意図せずそのスクリプトが実行されてしまう可能性があります。これがクロスサイトスクリプティング(XSS)と呼ばれる攻撃の一例です。
これを防ぐ基本がエスケープ処理。これは、<
や >
のような、プログラムにとって特別な意味を持つ文字を、単なる文字列として扱われる安全な形(例 <
や >
)に変換することです。
こうすれば、悪意のあるスクリプトもただの文字として表示されるだけで、実行されることはありません。出力するデータは、しっかり無害化してから出す。これもセキュアコーディングの鉄則です。
原則3:権限は最小限に認証と認可の考え方
システムには、管理者だけができる操作、一般ユーザーができる操作など、役割に応じた機能がありますよね。
ここで守りたいのが「最小権限の原則」です。これは、ユーザーやプログラムに、その役割を果たすために本当に必要な、一番小さい権限だけを与えましょう、という考え方。
例えば、ブログのコメント投稿機能を作るとして、コメントを投稿するだけのプログラムに、記事を削除できる権限まで与える必要はありませんよね?
もしそのプログラムに弱点が見つかって乗っ取られたとしても、できることが少なければ被害も最小限に抑えられます。
これを実現するために、まず認証(Authentication)で「あなた、本当に〇〇さん?」と本人確認をします。次に認可(Authorization)で「〇〇さん、あなたはこの操作をしてもOKですよ」と権限を確認・付与します。
誰に、どんな権限を、どこまで与えるか。これを適切に管理することが、プログラム全体の安全性を高める上でとても効いてきます。
プログラムを安全にする基本テクニック
基本原則がわかったところで、次はもう少し具体的に、初心者がよく出会う、そして対策が必須となる脆弱性と、その基本的な防ぎ方を見ていきましょう。
ここでは代表的な攻撃を2つ取り上げ、セキュアコーディングのテクニックを簡単な例で紹介しますね。
SQLインジェクションを防ぐ基本のコード
多くのWebサービスでは、ユーザー情報や商品情報などをデータベースに保存しています。このデータベースを操作する言語がSQLです。
SQLインジェクションとは、入力フォームなどに不正なSQL文を注入(インジェクション)されて、データベースを勝手に操作されたり、情報を盗まれたりする攻撃のこと。めっちゃ怖い!
例えば、ユーザーIDを入力させて、そのユーザーの情報を表示するプログラムがあったとします。
# 危ない例(ユーザー入力をそのままSQL文にくっつけてる) userId = "ユーザーが入力したID" query = "SELECT * FROM users WHERE id = '" + userId + "'" # このuserIdに ' OR '1'='1 とか入れられると大変なことに…
これを防ぐ基本中の基本がプレースホルダ(バインド機構)を使うことです。
# 安全な例(PythonのDB-API風) userId = "ユーザーが入力したID" query = "SELECT * FROM users WHERE id = ?" # 値が入る場所を ? で示す cursor.execute(query, (userId,)) # 値は別の引数として渡す
こんな風に、SQL文の骨組み(SELECT * FROM users WHERE id = ?
)と、そこに入れる値(userId
)を別々にデータベースに渡すのがポイント。
こうすれば、たとえuserId
にSQL文のような文字列が入っていても、それは単なる「値」として扱われ、SQL文の一部として解釈されることはありません。データベースを扱うプログラムでは、プレースホルダの使用は必須と考えましょう。
クロスサイトスクリプティングXSS対策の第一歩
先ほど「原則2」でも少し触れましたが、クロスサイトスクリプティング(XSS)は、Webサイトの入力フォームなどを通じて悪意のあるスクリプトを埋め込み、サイトを訪れた他のユーザーのブラウザ上で実行させる攻撃です。
これにより、個人情報(Cookieなど)が盗まれたり、偽のページに誘導されたりする可能性があります。
対策の基本は、ユーザーからの入力など、信頼できないデータをHTMLに出力する際に必ずエスケープ処理を行うことです。
# 危ない例(ユーザー入力をそのままHTMLに出力) userInput = "<script>alert('罠!')</script>" print("<p>" + userInput + "</p>") # これだと、ブラウザでスクリプトが実行されちゃうかも
多くのプログラミング言語やフレームワークには、HTMLエスケープのための関数が用意されています。
# 安全な例(Pythonのhtml.escapeを使う場合) import html userInput = "<script>alert('罠!')</script>" escapedInput = html.escape(userInput) # ここでエスケープ! print("<p>" + escapedInput + "</p>") # 出力結果例 <p><script>alert('罠!')</script></p> # これならスクリプトとして実行されない
このように、特別な意味を持つ文字(<
, >
, &
, "
など)を安全な文字エンティティ(<
, >
など)に変換します。動的にHTMLを生成する際は、出力値のエスケープを忘れない習慣をつけましょう。
安全なパスワード管理とエラーハンドリングの基本
ユーザーのパスワードを扱う場合、絶対にそのままデータベースに保存してはいけません! もしデータベースの情報が漏れたら、全ユーザーのパスワードが丸見えになってしまいます。
基本は、パスワードをハッシュ化して保存することです。ハッシュ化とは、元のデータを元に戻せない(不可逆な)別の値に変換する処理。
さらに安全性を高めるために、ソルトと呼ばれるランダムな値を加えてからハッシュ化するのが一般的です。
# 考え方のイメージ (あくまでイメージです) password = "ユーザーが設定したパスワード" salt = "ユーザーごとに生成したランダムな文字列" hashedPassword = hash_function(password + salt) # ハッシュ化 # データベースには hashedPassword と salt を保存する
もう一つ、エラーメッセージの扱いも気をつけたいポイント。
プログラムがエラーを起こしたとき、あまりに詳細なエラー情報(ファイルパス、SQL文、設定情報など)をそのままユーザーに見せてしまうと、攻撃者にシステムの内部情報や弱点を教えてしまうことになりかねません。
ユーザーには「エラーが発生しました。時間をおいて再度お試しください」のようなシンプルなメッセージだけを見せ、詳細なエラー情報は開発者だけが確認できるログファイルなどに出力するようにしましょう。
これも立派なセキュアコーディングです。
プログラムの安全性を高めるための基本ステップ
ここまで読んで、「よし、ちょっと意識してみようかな」と思っていただけたら嬉しいです!
セキュアコーディングは一日でマスターできるものではありませんが、日々の開発で少しずつ意識していくことが肝心です。
ここでは、皆さんが次の一歩を踏み出すためのヒントをいくつか紹介しますね。
セキュアコーディング学習におすすめのリソース
もっと深く学びたい、信頼できる情報がほしい、という方のために、いくつかおすすめのリソースを挙げておきます。
- OWASP Japan
- Webアプリケーションセキュリティに関する世界的なコミュニティの日本支部。たくさんの資料やツールが公開されています。特に「OWASP Top 10」は、よく見られる脆弱性のトップ10リストで、まず目を通しておくと良いでしょう。
- IPA(情報処理推進機構)「安全なウェブサイトの作り方」
- 日本の公的機関が出している、非常に分かりやすく実践的なガイドブック。具体的な脆弱性の解説と対策方法が豊富に載っています。初心者にもおすすめです。
- 各種プログラミング言語/フレームワークの公式ドキュメント
- 使っている言語やフレームワークの公式ドキュメントには、セキュリティに関するセクションやベストプラクティスが書かれていることが多いです。一度チェックしてみましょう。
これらの情報源を活用して、知識をアップデートし続けることが、安全なプログラム作りにつながります。
自分のコードを見直す簡単なチェックリスト
学んだことを早速活かしてみましょう! 自分の書いたプログラムや、これから書くプログラムを、以下の簡単なリストでチェックしてみてください。
- □ ユーザーからの入力値は、必ずチェック(バリデーション)していますか?
- □ Webページにデータを表示するとき、適切にエスケープ処理をしていますか?
- □ SQL文を組み立てるとき、プレースホルダを使っていますか?
- □ パスワードはハッシュ化して保存していますか?(できればソルト付きで)
- □ エラーが発生したとき、詳細な情報をユーザーに見せていませんか?
- □ 利用者に必要以上の権限を与えていませんか?
全部「はい」なら素晴らしい! もし「いいえ」があっても大丈夫。
それが、これから改善していくポイントです。まずはこのリストを使って、自分のコードの安全性を意識する癖をつけましょう。
【まとめ】プログラムの安全は基本から意識しよう
今回は、プログラムの安全の基本となるセキュアコーディングについて、その考え方と具体的なテクニックの初歩をお話ししてきました。
ポイントをまとめると…
- プログラムの安全は、機能と同じくらい基本的な開発要素。
- 「入力は疑う」「出力は無害化」「権限は最小限に」が基本原則。
- SQLインジェクションやXSSなど、よくある攻撃への対策は必須。
- プレースホルダやエスケープ処理など、基本的な防御テクニックを身につけよう。
- 学び続け、自分のコードをチェックする習慣が、安全性を高める。
セキュアコーディングは、決して難しい特別な技術ばかりではありません。今回紹介したような基本をしっかり押さえて、開発の初期段階から「これって安全かな?」と考える習慣をつけることが、何よりの防御になります。
この記事が、皆さんの安全なプログラム作りの第一歩となるきっかけになれば、とても嬉しいです。恐れずに、楽しみながら、セキュアな開発スキルを磨いていってくださいね!
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。