【はじめに】
毎日のように、サイバー攻撃や情報漏えいのニュースが世間を騒がせています。
これはなぜ起きるのでしょうか?
基本的にみなさんが仕事をしている会社ではセキュリティ対策を実施してはいますが
それは100%の安全を保証するものではありません。
会社の規模を問わず、問題は発生しています。
私達はシステム会社として携わっている以上、これらの問題とは切っても切り離せない位置にいます。
携わるシステムでセキュリティ侵害があったとき、対応に追われるのは自分になるからです。
「こんな重要性の低いコードに攻撃するやつなんていない、そもそもこのサーバは誰も知らない」と思うかもしれません。
たとえばAWSにwindowsServer2022を展開して、ファイアウォールやセキュリティ設定はデフォルトのままで公開したとします。
1時間の間に、18回も外部からアクセスが試行されたという検証結果があります。
産業スパイ、国家レベルの攻撃、暇を持て余している子供…犯罪者は世界中のサーバーを自動的に探索し、狙っています。
学生のころ、自分で暗号化処理を作ったことがあります。
プログラム内部で変換表を作って、全文字置き換えていくだけの極めて単純なものでした。
「ABCDE→4do9u」のような。
当時はこれでバレるわけないなんて思ってましたが、今の時代なら総当たりですぐばれちゃうでしょうね。
これくらいだったら大丈夫だろう…そんな小さな油断、その積み重ねが、システム攻撃の糸口になってしまいます。
システム開発者として考えるべき観点を考えていきましょう。
とはいえ、一気にたくさん列挙されても何から着手したらいいのか混乱してしまうと思います。
開発者・基盤担当・運用組織のそれぞれの観点毎に、セキュリティ成熟度レベルを用意しました。

- Lv1:基本の防御(最低限やらないといけないこと)
- Lv2:システムの堅牢化(より安全なシステムを目指す)
- Lv3:未然防止と復旧への備え(インシデントを未然に防ぎ、迅速に対応するための施策)
まずは自分のチームやプロジェクトがどのレベルまでできているのか確認しながら、可能であれば一歩ずつレベルを上げていきましょう!
【設計・コーディングの観点(開発者向け)】
Lv1
入力データを信用しない
外部からのデータを信用してはいけません。
フォームの入力値に、SQLインジェクションや悪意のあるコードが仕込まれているかもしれません。
ただし、自前でのサニタイズ(特殊文字の無害化)は避けてください。
抜け漏れによる新たな脆弱性を作りこむ事になります。
SQLであればプリペアードステートメントの利用を、文字列のサニタイズはフレームワークの機能やオープンソースのライブラリの利用を検討しましょう。
ORM(O/Rマッパー)を利用している場合でも油断は禁物です。
ORMでは表現しきれない複雑なクエリを『生のSQL』1で部分的に書く場合、そこがセキュリティホールになるケースが多発しています。
パスワードはハッシュ関数+ソルトを使用する
ユーザのログイン情報はどのように管理していますか?
もしパスワードをテキストファイルやDBにそのままの入力値で保存しているのであれば今すぐ改善が必要です。
現場でパスワード保存に使っているハッシュ関数を確認し、MD5やSHA-1などの古い実装を使っているのであれば、SHA-256や、より強力なbcrypt/Argon2などに変更できないか提案してみてください。
パスワード保存においては、必ずソルトを付与してください。
ハッシュ関数は不可逆変換ではありますが、単純なハッシュ値のまま保存するとレインボーテーブル攻撃で元の文字列が特定されてしまいます。
暗号化アルゴリズムを自作してはならない
暗号化処理の世界ではほんのどうでもいいような、些細なミスでも重大な結果を招きます。
事前にしっかりと調べて、可能であればしっかりアップデートされているオープンソースの暗号化処理を使いましょう。(openSSLなど)
Lv2
攻撃される範囲を最小化する(KISS/YAGNI)
複雑なコードは攻撃される可能性が高いです。(副作用で実装ミスを見落としやすい)
参照渡しよりも値渡しを、配列よりリストを。
より簡潔に、シンプルで小さなコードはそれだけセキュリティホールとなる可能性が減ります。
KISS原則2、YAGNI原則3を守りましょう。
私はRHELのパッチ情報を定期的に確認しているのですが、脆弱性の詳細情報を見ているとよくもまぁこんな不具合を見つけたな…と感心することが多いです。
遥かに高い意識をもってセキュリティに気を付けて作られているソフトウェアも、思わぬ実装箇所が脆弱性になってしまうことがあります。
なるべくシンプルな実装を保ち、攻撃される可能性を減らしましょう。
出力データは攻撃のヒントになる
ログイン画面で入力情報を間違った時、「そのユーザは存在しません」というメッセージを表示されているとどうでしょうか。
これは逆に存在するユーザを推測することができてしまいます。
また、エラーになったときにコンソールや画面にスタックトレースが出力されていませんか。
これはプログラムの脆弱性を見つけ出すヒントを与えてしまいます。
デバッグ用の文字が出力されているのも同様にNGです。
Web画面にユーザからの入力値を表示する際は、必ずエスケープ処理(HTMLエンティティ化) を行ってください。
JavaScriptのタグなどがそのまま実行されてしまうのを防ぐために必要な処理です。4
Lv3
サプライチェーン攻撃に注意する
近年はNPMやPyPIなどのパッケージリポジトリにマルウェアを混入させられる事件が発生しています。
利用するライブラリの信頼性の確認や、依存関係のチェック(SCAツールなど)を意識しましょう。
セキュリティ情報をチェックする
前述のサプライチェーン攻撃などの発生をいち早くつかむため、情報の感度をあげましょう。
JPCERTのサイトがとっつきやすいです。
https://www.jpcert.or.jp/
また、個人的にやっている施策ですが、Geminiを使って脆弱性情報を毎朝自動収集させ、チームの朝礼でメンバーに注意喚起しています。
自分から能動的にサイトを見に行かなくても、通勤途中や朝礼前にさっと確認することができるのでとてもおすすめです。
【インフラ・設定の観点(基盤担当向け)】
Lv1
セキュリティアップデートを適用する
OSのアップデート、ブラウザのアップデート、7zipのアップデートなど。
開発現場のソフトは最新のパッチが適用されていますか。
古い実行環境(たとえばjava6、java7…)やサポート切れのOS,フレームワーク(Windows10、seasor2…)を使っていませんか。5
OSやソフトの脆弱性を突いた攻撃は今も続いています。
特別な理由がない限り、最新のアップデートを適用しましょう。
認証の不要なサービスを公開しない
誰からでもアクセスできることになるので、それだけでDOS攻撃の原因になります。
最近発生したデータ漏洩の多くは、誰でもアクセスできる場所にデータを置いてしまったことが原因で起きています。
WEBに公開するサービスは必ず認証を要求するようにしましょう。
機密データを暗号化する
個人情報を含む帳票類、DBはどのように管理されていますか?
暗号化されず、誰でも見れる形で保存されているのであれば、非常に危険です。
DBであればDBそのものの暗号化(oracleなら透過的データ暗号化(TDE)などの機能があります)を検討しましょう。
アプリケーションや帳票出力サーバのキャッシュにも注意しましょう。
Lv2
接続元を絞る
nftablesなどを使い、可能な限りSSHを許可するIPアドレスを絞りましょう。
侵入口を減らすことで攻撃のリスクを減らすことができます。
特定の端末しか本番環境にアクセスできない、といった状況が作れればベストです。
認証できるユーザ数は最小化する
OS、DB、WEBシステムなどそれぞれのシステムの中で、退任者やもういない人のログインユーザーが残っていませんか。
もしくは、前任者のIDをそのまま使っていませんか。6
確実に使われない、使う予定のないIDがあれば可能な限り消しましょう。
デフォルトをセキュアなものにする
システムとしてなるべく安全な設定を心がけましょう。
例えばApacheであれば設定を見直し、バージョン情報の隠蔽、クリックジャギング対策、XSS対策、XST対策が行われているか確認しましょう。
余計なアプリを入れない
例えばLinuxならデフォルトでgccなどのコンパイラなどがインストールされていることがあります。
攻撃者にこれらを利用される可能性があるため、本番サーバでは開発ツール系のパッケージは削除、またはインストールしないようにしましょう。
※Pythonなどのランタイムについては、OSの動作に必要な場合があるので依存関係に注意しましょう
開発機にフリーソフトを入れるなども同様の理由で避けましょう。7
Lv3
WAF(Web Application Firewall)の導入
Webアプリケーション層への攻撃(SQLインジェクションやXSSなど)はファイアウォールだけでは防げません。
これらを検知・遮断するために、WAFの導入(クラウド型やOSSのModSecurityなど)を検討しましょう。
プログラム側の改修が間に合わない場合の一時的な対策としてもWAFは有効な手段となります。
ログの監視
エラーログや不審なアクセスログが出力されたときに、検知する仕組みは構築されていますか?
Linux標準機能であれば、rsyslogなど活用しましょう。
サーバーの時計を合わせる
ディジタルフォレンジックスの観点。
サーバーそれぞれの時刻は揃っていますか?
万一のトラブル発生時は、アクセスログや操作ログを時系列順に並べて被害状況を調べる必要があります。
正確な時刻同期が行われていない場合、それだけ調査の初動が遅れますし、攻撃者にアリバイを与えるようなものです。
【運用・組織の観点】
Lv1
アクセス情報をバージョン管理システムに登録しない。
SVN、gitなどバージョン管理システムにAPIキーやSSH鍵、暗号化パスワードがコミットされていませんか?
バージョン管理システムは便利ですが、真っ先に狙われるシステムでもあります。
社内サーバに作った独自リポジトリならまだ良いですが、クラウドリポジトリで公開設定を間違えたら…大変なことになります。
私が攻撃者なら、真っ先にバージョン管理システムにAPIキーが入っていないか狙います。
APIキーやDBパスワードは、ソースコードに直書きせず、環境変数(.envファイルなど) から読み込むように設計しましょう。
そして、.env ファイル自体は .gitignore に登録してコミット対象外にすることを徹底してください。
クラウド利用が多い場合はAzure Key VaultやAWS Secrets Managerなどの機密情報管理サービスの利用も検討しましょう。
もしAPIキーやパスワードが漏れた場合、不正利用されて数百万の請求が来たり、最悪の場合個人情報の流出もあり得ます。
この場合の信用失墜と、賠償金額を考えるとうっかりミスではすまされないリスクがあります。
会社の貸与PCはbitlockerで保護されているか?
SSD/HDDは抜き出して他端末から情報を抜き出す事ができます。
これを防止するのが暗号化です。
BIOSパスワードとは別物なので注意してください。
※macだとFileVault、LinuxだとLUKSが類似の技術です
オフラインバックアップは取られているか
運用しているシステムのバックアップ体制を確認しましょう。
ランサムウェア被害を万一受けた場合、オフラインバックアップがあればそこから復旧ができます。
NASなどオンラインバックアップもありますが、これはランサムの被害に遭ったりするリスクがあります。
オンラインバックアップ・オフラインバックアップの組み合わせが被害軽減のために大事です。
バックアップの基本は「3-2-1ルール(データは3つ保持、2種類の異なるメディア、1つはオフサイト/オフライン)」です。
ランサムウェアの被害金額はサイバー保険でもある程度補填されるかもしれませんがデータは保証されません。
オフラインバックアップはデータを守る最後の砦、業務停止やデータ消失のリスクから考えると低コストの事業継続保険と言えます。
Lv2
最小権限の原則を厳守する
すべてのユーザが管理者権限や全機能を扱う権限をもっていたりしませんか。
本当にこれを必要とする、最小限のユーザにのみ設定しましょう。
もし、アプリケーションに権限の概念がないのであれば、そこを是正できるか考えてみましょう。
多要素認証(MFA/2FA)を適用する
パスワードの複雑化や定期変更は、もはや古い考え方になりました。
2FA認証すらも、中間者攻撃などの危険性がありますが、純粋なパスワード認証よりは効果的です。
ブラウザのプラグインに注意
ブラウザのプラグインは広告ブロックなど便利なものもありますが、業務端末のブラウザに入れるのは避けましょう。
最初は問題なくても、後から悪意のあるプラグインに進化する攻撃が観測されています。
組織のポリシーとして、プラグインの導入は避けた方が安全です。
(グループポリシーの設定など検討しましょう)
※shadypanda
https://gigazine.net/news/20251204-browser-extension-malware/
Lv3
万が一のリストア計画は立てているか
企業データの14%は一切バックアップされておらず、バックアップデータのリカバリも2回に1回以上(58%)は失敗に終わっているという調査結果もあります。
せっかくとったバックアップも、使えなければ意味がありません。
バックアップはどこに取られているのかわかりますか?
バックアップからリストアする方法や手順を理解していますか?
万が一の時に慌てないように、復元手順を知っておきましょう。
私の現場では、業務上の理由があって定期的にリカバリを実施しています。
RDBMSレベルだけでなく、サーバーレベル、仮想化レイヤーがあるならコンテナレベルのリストア手順も用意しておきましょう。
【おわりに】
開発や運用作業をして疲れてくると、これぐらいは許されるだろう、と気が緩む瞬間があります。
この記事が現状の立ち位置を知り、小さな油断を取り除くための一助となれば幸いです。
皆様のチームやプロジェクトでは、どのレベルに位置していたでしょうか?
当記事は社内勉強会における啓蒙目的で作成したものですが、何かのお役に立てばと思い全体公開しました。
この記事を読まれた方で、「うちはこのような対策もしている」など情報がございましたら、コメントでお知らせいただけますと嬉しいです。
おまけとして、本記事で説明している観点をチェックリストとしてまとめました。
必要に応じてお使いください。
| 対象カテゴリ | レベル | チェック観点 | 実施状況 | 次のアクション | 担当者 | 対応期限 |
|---|---|---|---|---|---|---|
| 設計・コーディング(記載例) | Lv1 | 入力データを信用しない(サニタイズは自前で行わずライブラリ等を利用) | 未着手 | プロジェクト内のSQLを調査し、バインド変数を使わずに直接SQL文を組み立てているSQLを洗い出す。 | XXさん | 2026/2/5 |
| 設計・コーディング | Lv1 | 入力データを信用しない(サニタイズは自前で行わずライブラリ等を利用) | ||||
| 設計・コーディング | Lv1 | パスワードはハッシュ関数+ソルトを使用して保存する | ||||
| 設計・コーディング | Lv1 | 暗号化アルゴリズムを自作しない | ||||
| 設計・コーディング | Lv2 | 攻撃される範囲を最小化する(KISS/YAGNI原則の遵守) | ||||
| 設計・コーディング | Lv2 | 出力データによる攻撃ヒントの提示を防ぐ | ||||
| 設計・コーディング | Lv3 | サプライチェーン攻撃への警戒とSCAツールの活用 | ||||
| 設計・コーディング | Lv3 | 能動的なセキュリティ情報の収集と展開 | ||||
| インフラ・設定 | Lv1 | 最新のセキュリティアップデートを適用する | ||||
| インフラ・設定 | Lv1 | 認証の不要なサービスを外部公開しない | ||||
| インフラ・設定 | Lv1 | 機密データ(DB・帳票等)を暗号化する | ||||
| インフラ・設定 | Lv2 | 接続元IPアドレスを絞り込む | ||||
| インフラ・設定 | Lv2 | 認証ユーザー数を最小化し、不要なIDを削除する | ||||
| インフラ・設定 | Lv2 | ミドルウェア設定をセキュアなデフォルトにする | ||||
| インフラ・設定 | Lv2 | 本番サーバーに不要なアプリや開発ツールを入れない | ||||
| インフラ・設定 | Lv3 | WAF(Web Application Firewall)を導入する | ||||
| インフラ・設定 | Lv3 | ログの監視・検知の仕組みを構築する | ||||
| インフラ・設定 | Lv3 | 全サーバーの時刻同期を正確に行う | ||||
| 運用・組織 | Lv1 | 機密情報をバージョン管理システムに登録しない | ||||
| 運用・組織 | Lv1 | 貸与PCのディスク暗号化(BitLocker等) | ||||
| 運用・組織 | Lv1 | オフラインバックアップの取得(3-2-1ルール) | ||||
| 運用・組織 | Lv2 | 最小権限の原則を厳守する | ||||
| 運用・組織 | Lv2 | 多要素認証(MFA/2FA)を適用する | ||||
| 運用・組織 | Lv2 | ブラウザプラグインの導入制限 | ||||
| 運用・組織 | Lv3 | リストア計画の策定と定期的な復元演習 |
参考文献
- 達人プログラマー第二版
- Medium:How long can an insecure server survive online before it gets hacked? https://digitalenabling.medium.com/how-long-can-an-insecure-server-survive-online-before-it-gets-hacked-9b1c74ed723c#:~:text=The%20entire%20internet%20is%20constantly%20being%20scanned,on%20compliance%20requirements%20to%20drive%20their%20patching.
- IPA:セキュリティ対策の基本と共通対策 情報セキュリティ10大脅威 2024版 https://www.ipa.go.jp/security/10threats/nq6ept000000g23w-att/kihontokyoutsuu_2024.pdf
- オフサイトバックアップサービス https://note.com/calm_nerine9307
- VMware/Hyper-V、クラウド対応ツール技術ブログ https://www.climb.co.jp/blog_veeam/veeam-20506
- トレンドマイクロ:NPMサプライチェーン攻撃の現状と分析 https://www.trendmicro.com/ja_jp/research/25/i/npm-supply-chain-attack.html
- Security NEXT:PyPI上に不正コード含む「num2words」 - 開発者がフィッシング被害 https://www.security-next.com/172964
- The Python Package Index Blog:Preventing Domain Resurrection Attacks https://blog.pypi.org/posts/2025-08-18-preventing-domain-resurrections/
- Snyk株式会社:ソフトウェア構成分析(SCA)ツールの選び方 https://qiita.com/SnykSec/items/171062b11b8a107588fe
-
ORMのPrismaで、シンプルにLEFTJOINしたいだけなのにスマートに実現できず、やむを得ずqueryRawUnsafeを使った経験があります。 ↩
-
Keep It Simple Stupid(シンプルで愚鈍にする)
プログラムは同じ結果を様々な実装で実現することができる。その中で最もシンプルな実装方法を選ぶ。 ↩ -
You aren't gonna need it(実際に必要になるまで機能を追加しない)
予期しない変更に対しては、設計を単純にすることが備えとなる。そして、必要以上の機能を追加すると、設計が複雑になってしまう。 ↩ -
もうサービス終了しましたが、ユーザー名にcolorやフォントサイズなどのタグ指定がそのまま使えてしまったせいで、ユーザ名表示やランキングがえらいことになった伝説のソシャゲがありましたね。 ↩
-
新人時代の話ですが、Windows8が全盛の時代にWindows2000のシステムを保守したことがあり、びっくりした記憶が残っています。 ↩
-
緊急で代理作業する時や、担当者引継ぎ時に前任者のIDをとりあえず使ったはいいものの、そのまま前任者のIDを使いつづけて数年…という現場に遭遇したことがあります。 ↩
-
これは新人の頃かつ大らかな現場なので許されていたことですが、報連相が遅れてよく上司に怒られていたので
開発機で使っているVisualStudioで15分おきに「報連相したか?」ってアラートを上げるアプリを作って運用していたことがあります。
今の時代だと監査ソフトとか入ってるので、変なプログラムが常駐してる!って検知されてしまうかもしれませんね。 ↩