プログラミング/セキュリティ
セキュリティの概要
[編集]セキュリティとは
[編集]セキュリティとは、情報やシステムの機密性、完全性、可用性を脅威から守ることを指します。適切なセキュリティ対策がなされていないと、重要データの漏洩、改竄、サービス停止などの被害が発生する可能性があります。
セキュリティの3大要素
[編集]セキュリティには以下の3つの要素があります。
- 機密性(Confidentiality)
- 許可されたユーザ/エンティティだけがデータにアクセスできること
- 完全性(Integrity)
- データが不当に変更または破壊されないこと
- 可用性(Availability)
- システムやデータが必要な時に利用できること
これらの要素を守ることがセキュリティの目的です。
セキュリティ脅威の種類
[編集]セキュリティを脅かす要因としては、次のようなものがあげられます。
- 不正アクセス(攻撃者による不正な侵入)
- 人的ミス(作業者の誤操作や negligence)
- 自然災害(地震、火災など)
- システム障害(ハードウェア、ソフトウェアの不具合)
アクセス制御
[編集]認証と認可の違い
[編集]アクセス制御とは、許可されたユーザにのみシステムへのアクセスを許可する仕組みです。認証(Authentication)とは、利用者の本人確認を行う処理です。一方、認可(Authorization)とは、認証済みの利用者に対して、許可されたリソースへのアクセス権を与える処理を指します。
認証方式
[編集]代表的な認証方式には以下のようなものがあります。
- 知識に基づく認証(パスワード、PINコードなど)
- 所有物に基づく認証(ICカード、ハードウェアトークンなど)
- 生体認証(指紋、静脈、虹彩、顔認証など)
高いセキュリティを確保するには、これらを組み合わせた多要素認証を行うことが推奨されています。
権限管理とアクセス制御モデル
[編集]認可に関しては、利用者に与える権限をきちんと管理する必要があります。アクセス制御モデルとしては、DAC(Discretionary Access Control)、MAC(Mandatory Access Control)、RBAC(Role-Based Access Control)などがあります。また、最小権限の原則に則り、利用者に必要最小限の権限しか与えないようにすることが重要です。
暗号化技術
[編集]共通鍵暗号方式と公開鍵暗号方式
[編集]暗号技術には、共通鍵暗号方式と公開鍵暗号方式の2種類があります。共通鍵暗号方式は、送信者と受信者が同じ鍵を共有し、その鍵で平文を暗号化/復号します。一方の公開鍵暗号方式は、暗号化と復号に異なる鍵(公開鍵と秘密鍵)を使う方式です。
ハッシュ関数とメッセージ認証コード
[編集]ハッシュ関数はデータから固定長の値(ハッシュ値)を生成する単方向の関数で、データの完全性を検証する際に利用されます。メッセージ認証コード(MAC)は、ハッシュ値に秘密の鍵を用いることで、データの完全性と真正性の両方を確保できる仕組みです。
暗号化通信
[編集]SSL/TLSはインターネット上の通信を暗号化する代表的なプロトコルです。クライアントとサーバ間で事前に共有鍵を交換し、その後の通信内容を共通鍵暗号方式で暗号化します。正当なサーバを証明するため、公開鍵基盤(PKI)に基づく公開鍵の署名と検証が行われます。
入力とエスケープ
[編集]信頼できないデータとは
[編集]Webアプリケーションなどでは、ユーザから入力を受け取る必要がありますが、入力データを安易に信用してはいけません。攻撃者からの悪意のある入力値(信頼できないデータ)が原因で、セキュリティホールが発生する可能性があるためです。
入力データの検証と無害化
[編集]そのため、ユーザ入力に対しては、事前に適切な検証を行い、許可されていない値などをフィルタリングする必要があります。さらに、ユーザ入力をシステムに渡す前に、その値を無害化(エスケープ、サニタイズ)する処理も不可欠です。
攻撃手法の例
[編集]入力値を適切に処理しないと、SQLインジェクション、XSSなどの攻撃を受ける可能性があります。SQLインジェクションはユーザ入力にSQLコマンドを仕込んでデータベースを不正操作する攻撃で、XSSはユーザ入力にスクリプトを仕込んでWebブラウザ上で不正なコードを実行させる攻撃です。コマンドインジェクションなども同様の手口です。
セキュアコーディング
[編集]脆弱性の種類とその対策
[編集]セキュアコーディングとは、ソフトウェアの脆弱性を作り込まないための開発手法のことです。代表的な脆弱性としては、バッファオーバーフロー、フォーマット文字列攻撃、整数オーバーフロー、nullポインタ参照、レースコンディションなどがあげられます。これらの脆弱性に対処するには、安全なコーディング規約に従うことが重要です。
安全なAPI/ライブラリの利用
[編集]さらに、使用するAPIやライブラリも、セキュリティ上のリスクがないものを選ぶ必要があります。安全でないAPIやライブラリを使うと、意図せずセキュリティホールを作り込んでしまう可能性があります。
最小権限の原則と防御の多層化
[編集]ソフトウェアの設計においては、最小権限の原則に従い、必要最小限の権限しか与えないようにすることが大切です。また、単一の対策に依存するのではなく、防御を多層化することで、より堅牢なセキュリティを実現できます。
システム全体のセキュリティ
[編集]OSとアプリケーションのセキュリティ更新
[編集]システム全体のセキュリティを確保するためには、OSやミドルウェア、アプリケーションなどのソフトウェアについて、セキュリティ修正プログラムを適用することが重要です。ベンダーから脆弱性の報告があれば、速やかに修正プログラムを適用する必要があります。
ファイアウォール/IPS/IDSなどの導入
[編集]ネットワークを介した不正アクセスからシステムを守るには、ファイアウォールの導入が有効です。さらに、IPSやIDSなどの侵入防止/侵入検知システムを組み合わせることで、より確実な対策が可能になります。
セキュリティポリシーと監査
[編集]システム全体のセキュリティを適切に運用・管理していくため、セキュリティポリシーを定める必要があります。ポリシーには、業務に応じてアクセスを制限するルールや、インシデント発生時の対応手順などを定めます。また、ポリシーが守られているかを定期的に監査し、是正する体制を整えることが重要です。
セキュリティ開発ライフサイクル
[編集]設計レビュー
[編集]セキュリティは、アプリケーションの設計段階から意識しておく必要があります。設計についてセキュリティ専門家によるレビューを受け、適切な認証/認可機能の実装や、安全なアーキテクチャの採用を検討します。
脆弱性スキャニング
[編集]実装が完了した段階で、ソースコードや実行バイナリに対して、静的解析やフォーツ解析、ペネトレーションテストなどを行い、セキュリティ上の脆弱性をスキャンします。見つかった脆弱性は修正する必要があります。
penetration test
[編集]完成したシステムに対しては、第三者によるペネトレーションテスト(侵入検査)を実施し、残された脆弱性を洗い出します。侵入検査で見つかった問題点は確実に修正する必要があります。
セキュリティ教育
[編集]システムを安全に保つため、システム開発者だけでなく、最終利用者に対するセキュリティ教育も欠かせません。安全なパスワードの選び方や、不審なメールへの対処方法など、基本的なリテラシーを身に付けさせる必要があります。
最新のセキュリティ動向
[編集]新しい脅威とその対策
[編集]セキュリティ分野では、新しい種類の脅威が常に発生しています。ゼロデイ攻撃、IoT機器の脆弱性、AIシステムへの攻撃など、最新の脅威とその対策方法を確認し続ける必要があります。
セキュリティ分野の最新技術や研究動向
[編集]一方で、セキュリティを守る新しい技術や研究が、日々生み出されています。フォーマル検証によるコード検証、アクセス制御のための最新の認証手法の研究、暗号技術の進化などについて、最新動向を確認し続けることが重要です。
セキュリティは、システムやアプリケーションの設計から実装、運用に至るすべての過程で意識し続ける必要があります。さらに、セキュリティ技術の進化に追随し、最新の脅威に備えた対策を講じることが不可欠です。企業や個人が安全にITを利用できる環境を実現するため、セキュリティ対策は常に継続的な改善が求められます。