Express.jsでAPIやWebアプリを作れるようになると、次に気になるのが「このまま本番公開しても大丈夫なのか?」という点です。
ローカル環境で動くアプリでも、本番環境ではセキュリティ面の注意点が増えます。
たとえば、以下のような不安はないでしょうか。
- Express.jsで最低限やるべきセキュリティ対策を知りたい
- Helmet、Cookie、TLSなどの基本を整理したい
- 個人開発アプリを本番公開する前に確認したい
- 公式ドキュメントの内容を初心者向けに理解したい
- Node.jsとExpress.jsで安全なAPIを作りたい
結論から言うと、Express.jsを本番環境で使うなら、最低限以下の対策を確認しておくべきです。
対策 | 目的 |
|---|---|
非推奨・脆弱なExpress.jsを使わない | 既知の脆弱性を避ける |
TLSを使う | 通信を暗号化する |
ユーザー入力を信頼しない | 不正な入力やopen redirectを防ぐ |
Helmetを使う | セキュリティ関連HTTPヘッダーを設定する |
フィンガープリントを減らす | 使用技術を推測されにくくする |
Cookieを安全に使う | セッションや認証情報の悪用を防ぐ |
ブルートフォース攻撃を防ぐ | ログイン試行の総当たりを防ぐ |
依存関係を安全に保つ | npmパッケージ由来の脆弱性を減らす |
この記事では、Express.js公式ドキュメントの「セキュリティのベストプラクティス」をもとに、初心者にも分かりやすく解説します。
Express.jsのセキュリティ対策で最初に理解すべきこと
Express.jsのセキュリティ対策で最初に理解すべきことは、開発環境と本番環境では求められる安全性が違うという点です。
開発中は、エラー内容を詳しく表示したり、ログを細かく出したりすることがあります。
これは開発効率を上げるためには便利です。
しかし、本番環境では事情が変わります。
本番環境では、アプリケーションが外部ユーザーに公開されます。
そのため、開発中には問題になりにくかった以下のような設定が、セキュリティ上のリスクになることがあります。
- エラー情報を詳しく出しすぎる
- 古いExpress.jsや依存パッケージを使い続ける
- Cookieの設定が甘い
- ユーザー入力をそのまま使う
- ログイン試行回数を制限していない
- HTTPヘッダーのセキュリティ設定をしていない
つまり、Express.jsのセキュリティ対策は「アプリが動くようになった後」に必ず確認すべき作業です。
個人開発やポートフォリオでも、本番公開するなら最低限の対策はしておきましょう。
非推奨・脆弱なExpress.jsバージョンを使わない
結論として、古いExpress.jsや脆弱性があるバージョンは使わないようにしましょう。
理由は、メンテナンスされていないバージョンでは、セキュリティやパフォーマンス上の問題が修正されないためです。
Express.js公式ドキュメントでは、Express 2.xと3.xはメンテナンスされていないため、使用しないように案内されています。
初心者が見落としやすいのは、「昔の教材や古い記事を見ながら環境構築してしまう」ケースです。
たとえば、以下のような場合は注意が必要です。
- 古い技術ブログを参考にしている
- 何年も前のサンプルコードをコピーしている
- package.jsonのバージョンを確認していない
- npm install後に脆弱性警告を見ていない
最低限、以下のように現在使っているExpress.jsのバージョンを確認しておくとよいです。
npm list express
また、脆弱性チェックとして後述する npm audit も確認しておきましょう。
TLSを使って通信を暗号化する
結論として、機密データを扱うExpress.jsアプリでは、TLSを使って通信を暗号化するべきです。
TLSとは、クライアントとサーバー間の通信を暗号化する仕組みです。
一般的には、WebサイトをHTTPS化するときに使われます。
ユーザーがログイン情報や個人情報を送信する場合、通信が暗号化されていないと、通信内容を盗み見られるリスクがあります。
Express.js公式ドキュメントでは、機密データを扱ったり転送したりする場合は、TLSを使用して接続とデータを保護すると説明されています。
初心者向けに言うと、以下のようなアプリでは特に重要です。
- ログイン機能があるアプリ
- お問い合わせフォームがあるアプリ
- 個人情報を扱うアプリ
- 管理画面があるアプリ
- APIキーや認証情報を扱うAPI
公式ドキュメントでは、一般的にNginxでTLSを扱うことが推奨されています。
また、無料のTLS証明書を取得できる手段としてLet’s Encryptにも触れられています。
ただし、NginxやLet’s Encryptの具体的な設定手順は環境によって変わります。
本番環境にデプロイする際は、利用しているサーバー、クラウド、ホスティングサービスの公式情報も確認してください。
ユーザー入力を信頼しない
結論として、ユーザーが入力した値をそのまま信用してはいけません。
Webアプリケーションでは、フォーム、URLクエリ、リクエストボディ、Cookieなど、さまざまな形でユーザー入力を受け取ります。
しかし、ユーザー入力には悪意ある値が含まれる可能性があります。
Express.js公式ドキュメントでは、Webアプリケーションにおける重要なセキュリティ要件の一つとして、適切なユーザー入力の検証と処理が挙げられています。
初心者が特に注意したいのが、open redirectです。
open redirectとは、ユーザー入力として受け取ったURLに対して、そのまま res.redirect() してしまうような問題です。
たとえば、ログイン後の遷移先を ?url=... のようなクエリで受け取り、そのままリダイレクトすると、悪意あるサイトへ誘導される可能性があります。
公式ドキュメントでは、res.redirect や res.location を使う前にURLをチェックする例が紹介されています。
考え方としては、以下のような流れです。
app.use((req, res) => {
try {
if (new URL(req.query.url).host !== 'example.com') {
return res.status(400).end(`Unsupported redirect to host: ${req.query.url}`);
}
} catch (e) {
return res.status(400).end(`Invalid url: ${req.query.url}`);
}
res.redirect(req.query.url);
});
ポイントは、ユーザーから受け取ったURLをそのまま信用しないことです。
実務では、許可する遷移先をあらかじめ決めておく、想定外のホストにはリダイレクトしない、といった考え方が重要になります。
HelmetでHTTPヘッダーを安全に設定する
結論として、Express.jsアプリではHelmetを導入して、セキュリティ関連のHTTPヘッダーを設定しましょう。
Helmetは、Express.jsのHTTPレスポンスヘッダー設定を支援するミドルウェアです。
HTTPヘッダーとは、ブラウザとサーバーの通信時に送られる追加情報のようなものです。
Express.js公式ドキュメントでは、HelmetはHTTPヘッダーを適切に設定することで、よく知られているWeb脆弱性からアプリを保護するのに役立つと説明されています。
導入はシンプルです。
npm install helmet
Express.js側では以下のように使います。
const helmet = require('helmet');
app.use(helmet());
Helmetはデフォルトで、複数のセキュリティ関連ヘッダーを設定します。
代表的なものは以下です。
ヘッダー | 役割 |
|---|---|
Content-Security-Policy | ページで許可する動作を制御し、多くの攻撃を軽減する |
Strict-Transport-Security | ブラウザにHTTPSを優先するよう伝える |
X-Content-Type-Options | MIME sniffingを避ける |
X-Frame-Options | クリックジャッキング攻撃を軽減する |
Referrer-Policy | Refererヘッダーの扱いを制御する |
X-Powered-By | Helmetでは削除される |
Helmetを入れるメリットは、初心者でもセキュリティ関連ヘッダーをまとめて設定しやすいことです。
一方で、注意点もあります。
Helmetを入れればすべてのセキュリティ対策が終わるわけではありません。
Cookie、入力検証、TLS、依存関係のチェックなどは別途必要です。
また、Content-Security-Policyなどはアプリの構成によって調整が必要になる場合があります。
設定を変更する場合は、Helmet公式ドキュメントや利用時点の公式情報も確認してください。
フィンガープリントを減らす
結論として、Express.jsアプリでは、サーバーがExpress.jsであることを推測されにくくする工夫も有効です。
フィンガープリントとは、サーバーの応答やHTTPヘッダーなどから、使っているソフトウェアを推測されることです。
Express.jsはデフォルトで X-Powered-By レスポンスヘッダーを送信します。
公式ドキュメントでは、以下のように無効化できると説明されています。
app.disable('x-powered-by');
これにより、カジュアルな攻撃者に対して、Express.jsを使っていることを見えにくくできます。
ただし、公式ドキュメントでも説明されているように、X-Powered-By を無効化しても、洗練された攻撃者がExpress.jsを使っていることを判断できないわけではありません。
つまり、これは単独で強力な防御策というより、セキュリティ姿勢を少し改善するための追加対策と考えるべきです。
また、Express.jsは独自の404エラーメッセージやエラー応答メッセージを返すことがあります。
公式ドキュメントでは、独自の404ハンドラやエラーハンドラを追加する例も示されています。
// custom 404
app.use((req, res, next) => {
res.status(404).send("Sorry can't find that!");
});
// custom error handler
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
本番環境では、エラーの詳細をユーザーに見せすぎないことも重要です。
Cookieとセッションを安全に扱う
結論として、Express.jsでCookieやセッションを使う場合は、デフォルト名を避け、セキュリティオプションを適切に設定しましょう。
Cookieとは、ブラウザに保存される小さなデータです。
ログイン状態の管理やセッション管理に使われることがあります。
Express.js公式ドキュメントでは、Cookieを悪用されないように、以下の2点が重要だと説明されています。
- デフォルトのセッションクッキー名を使わない
- Cookieのセキュリティオプションを適切に設定する
デフォルトのセッションクッキー名を使わない
結論として、セッションCookieにはデフォルト名ではなく、一般的な名前を設定しましょう。
理由は、デフォルトのセッションクッキー名を使うと、攻撃者がアプリの構成を推測しやすくなる可能性があるためです。
公式ドキュメントでは、express-session を使った以下のような例が示されています。
const session = require('express-session');
app.set('trust proxy', 1);
app.use(
session({
secret: 's3Cur3',
name: 'sessionId',
})
);
ここでは、セッションCookie名として sessionId を指定しています。
注意点として、上記の secret は例示用です。
実際の本番環境では、推測されにくい値を利用し、コードに直接ベタ書きしないようにするなど、環境に応じた管理が必要です。
この補足は公式ページのコード例を実運用で扱う際の一般的な注意点です。利用時点の公式情報や利用ライブラリのドキュメントも確認してください。
Cookieのセキュリティオプションを設定する
結論として、Cookieには secure や httpOnly などのオプションを適切に設定しましょう。
Express.js公式ドキュメントでは、Cookieのセキュリティ強化に関係するオプションとして、以下が紹介されています。
オプション | 意味 |
|---|---|
secure | HTTPS経由でのみCookieを送信できるようにする |
httpOnly | クライアントJavaScriptではなくHTTP(S)上でのみ送信されるようにする |
domain | Cookieの対象ドメインを指定する |
path | Cookieの対象パスを指定する |
expires | 永続的Cookieの有効期限を指定する |
公式ドキュメントでは、cookie-session を使った例も示されています。
const session = require('cookie-session');
const express = require('express');
const app = express();
const expiryDate = new Date(Date.now() + 60 * 60 * 1000);
app.use(
session({
name: 'session',
keys: ['key1', 'key2'],
cookie: {
secure: true,
httpOnly: true,
domain: 'example.com',
path: 'foo/bar',
expires: expiryDate,
},
})
);
secure: true はHTTPS経由でのみCookieを送信するための設定です。httpOnly: true は、クライアント側JavaScriptからCookieにアクセスされにくくするための設定です。
ログイン機能を持つアプリでは、Cookie設定を軽視しないようにしましょう。
express-sessionとcookie-sessionの違い
結論として、セッションデータをどこに保存するかによって、使うミドルウェアの考え方が変わります。
Express.js公式ドキュメントでは、主なセッションミドルウェアとして express-session と cookie-session が紹介されています。
ミドルウェア | 特徴 | 注意点 |
|---|---|---|
express-session | セッションデータをサーバー側に保存し、CookieにはセッションIDのみ保存する | デフォルトのインメモリストレージは本番環境向けではない |
cookie-session | セッション全体をCookieにシリアライズする | セッションデータが小さく、クライアントに見えても問題ない場合に向く |
公式ドキュメントでは、express-session はデフォルトでインメモリストレージを使うため、本番環境用に設計されておらず、本番ではスケーラブルなsession-storeを設定する必要があると説明されています。
一方、cookie-session はセッション全体をCookieに保存します。
そのため、セッションデータが比較的小さく、クライアントに見えても問題ない内容の場合にのみ使うべきです。
初心者向けに言うと、ログイン状態や認証に関わるセッション設計は、なんとなくで実装しない方がよいです。
公式情報や利用するミドルウェアのドキュメントを確認し、アプリの要件に合わせて選びましょう。
ログインへのブルートフォース攻撃を防ぐ
結論として、ログイン機能があるExpress.jsアプリでは、ログイン試行回数を制限する仕組みを検討しましょう。
ブルートフォース攻撃とは、IDやパスワードを何度も試してログインを突破しようとする攻撃です。
Express.js公式ドキュメントでは、ログインエンドポイントを保護するためのシンプルで強力な手法として、以下の2つの指標を使って認証試行をブロックする方法が紹介されています。
- 同じユーザー名とIPアドレスによる連続失敗回数
- 長期間におけるIPアドレス単位の失敗回数
たとえば、同じIPアドレスから1日に100回失敗した場合、そのIPアドレスをブロックする、といった考え方です。
公式ドキュメントでは、この手法を簡単かつ高速にするツールとして rate-limiter-flexible パッケージも紹介されています。
ただし、具体的な実装方法はアプリの認証仕様によって変わります。
ログイン機能を実装する場合は、利用する認証ライブラリや公式ドキュメントもあわせて確認してください。
依存関係の脆弱性をチェックする
結論として、Express.js本体だけでなく、npmで入れている依存パッケージの脆弱性も確認しましょう。
Node.jsアプリでは、Express.js以外にも多くのnpmパッケージを使います。
便利な一方で、依存パッケージに脆弱性があると、アプリ全体のセキュリティにも影響します。
Express.js公式ドキュメントでは、アプリのセキュリティは依存関係の「最も弱いリンク」と同じくらい強力だと説明されています。
最低限、以下のコマンドで依存関係の脆弱性を確認できます。
npm audit
また、公式ドキュメントではSnykも紹介されています。
npm install -g snyk
cd your-app
snyk test
npm audit やSnykは、依存パッケージに既知の脆弱性がないか確認するための手段です。
初心者がやりがちな失敗は、以下です。
- npm install時の警告を無視する
- package.jsonを長期間更新しない
- 古い教材のバージョン指定をそのまま使う
- 依存関係の脆弱性チェックを本番公開前にしない
個人開発でも、デプロイ前には npm audit を確認する習慣をつけましょう。
その他のセキュリティ上の考慮事項
結論として、Express.jsアプリは一般的なWebアプリと同じく、さまざまなWeb脆弱性に注意する必要があります。
Express.js公式ドキュメントでは、追加の考慮事項として以下のような対策にも触れられています。
- XSSやコマンドインジェクション対策として、ユーザー入力をフィルタリング・サニタイズする
- SQLインジェクション対策として、パラメータ化されたクエリや準備された文を使う
- SQLインジェクション検出にsqlmapを使う
- SSL暗号設定のテストにnmapやsslyzeを使う
- safe-regexを使って正規表現DoS攻撃の影響を受けないようにする
ここで重要なのは、Express.jsだけでセキュリティが完結するわけではないという点です。
データベース、認証、Cookie、外部API、フロントエンド、インフラ設定など、Webアプリ全体で安全性を考える必要があります。
Express.jsセキュリティ対策チェックリスト
本番公開前には、以下のチェックリストを確認しましょう。
チェック項目 | 確認 |
|---|---|
Express.jsが古い非推奨バージョンではない | □ |
脆弱なExpress.jsバージョンを使っていない | □ |
HTTPS/TLSを使っている | □ |
ユーザー入力を検証している | □ |
open redirectを防いでいる | □ |
Helmetを導入している | □ |
X-Powered-Byを無効化している | □ |
独自の404ハンドラを用意している | □ |
独自のエラーハンドラを用意している | □ |
デフォルトのセッションCookie名を使っていない | □ |
Cookieにsecure/httpOnlyなどを設定している | □ |
ログイン試行回数を制限している | □ |
npm auditを確認している | □ |
必要に応じてSnykなども確認している | □ |
入力値のフィルタリング・サニタイズを検討している | □ |
このチェックリストをすべて満たせば完璧という意味ではありません。
しかし、Express.js公式ドキュメントで紹介されている基本的な対策を見落としにくくなります。
初心者がつまずきやすいポイント
Express.jsのセキュリティ対策で、初心者がつまずきやすいポイントを整理します。
Helmetを入れれば全部OKだと思ってしまう
Helmetは便利ですが、万能ではありません。
Helmetが担当するのは、主にHTTPレスポンスヘッダーの設定です。
Cookie設定、入力検証、TLS、依存関係チェックなどは別途必要です。
Cookieの設定を後回しにする
ログイン機能を作るとき、動作確認だけを優先してCookie設定を後回しにしがちです。
しかし、本番環境ではCookieの扱いが重要です。
secure や httpOnly などの設定は、早めに確認しておきましょう。
古い記事のコードをそのまま使う
Express.jsやNode.js周辺の情報は、古い記事も多いです。
特に、Express 2.xや3.xに関する情報、古いミドルウェアの使い方には注意が必要です。
npm auditの警告を無視する
npmパッケージの脆弱性は、アプリ全体に影響する可能性があります。
本番公開前には、依存関係の脆弱性を確認する習慣をつけましょう。
Express.js学習におすすめの書籍
ここまで、Express.js公式ドキュメントをもとにセキュリティ対策を解説しました。
ただ、初心者の場合は、セキュリティだけを単体で学ぶより、Express.jsやNode.jsの基礎、Webアプリの設計、本番運用の考え方も一緒に学ぶと理解しやすくなります。
ここでは、目的別に関連書籍を紹介します。
Express.jsの基礎から学びたい人向け:作りながら学ぶWebプログラミング実践入門
Express.jsの基礎から学びたい初学者には、「作りながら学ぶWebプログラミング実践入門」が向いています。
この本は、セキュリティ専門書というより、Express.jsやWebアプリ開発の基礎を手を動かしながら理解するための入門書として考えるとよいです。
向いている人は以下です。
- Express.jsの基礎から学びたい人
- Webアプリ開発の全体像を理解したい人
- Reactなどのフロントエンド連携も含めて学びたい人
- いきなりセキュリティ対策に入る前に、まずアプリを作れるようになりたい人
一方で、Express.jsのセキュリティ専門書として読む本ではありません。
まずはアプリを作る流れを学び、その後に本記事のようなセキュリティ対策を確認する流れがおすすめです。
本番運用や速度改善も意識したい人向け:達人が教えるWebパフォーマンスチューニング
Express.jsを本番運用するなら、セキュリティだけでなくパフォーマンス面も重要です。
「達人が教えるWebパフォーマンスチューニング」は、Webアプリの速度改善や負荷対策を学びたい人に向いています。
Express.jsそのものの入門書というより、実運用の品質を高めるための本として考えるとよいです。
向いている人は以下です。
- Express.jsアプリを本番公開したい人
- Webアプリの速度改善や負荷対策を学びたい人
- セキュリティだけでなく、運用品質も高めたい人
- Node.js対応のパフォーマンス改善に関心がある人
一方で、Express.jsを初めて触る人には少し早いかもしれません。
まずはExpress.jsの基礎を学び、アプリを作れるようになってから読むと理解しやすいです。
Node.jsの設計力を高めたい人向け:Node.jsデザインパターン
Express.jsでアプリを作れるようになった後に課題になるのが、保守しやすい設計です。
「Node.jsデザインパターン」は、Node.jsの非同期処理、モジュール設計、バックエンドアーキテクチャの考え方を深く学びたい人に向いています。
Express.jsのセキュリティ対策だけでなく、長期的にメンテナンスしやすい設計を学びたい人におすすめしやすい本です。
向いている人は以下です。
- Express.jsやNode.jsの基礎をある程度学んだ人
- 非同期処理を体系的に理解したい人
- 保守しやすいアプリケーション設計を学びたい人
- 実務レベルのバックエンド設計に近づきたい人
一方で、完全な初心者向けではありません。
Express.jsで簡単なAPIを作った経験がある人が、次のステップとして読むと効果的です。
FAQ
Express.jsで最低限やるべきセキュリティ対策は何ですか?
最低限確認したいのは、古いExpress.jsを使わないこと、TLSの利用、ユーザー入力の検証、Helmetの導入、Cookieの安全な設定、ブルートフォース攻撃対策、依存関係の脆弱性チェックです。
特に本番公開前には、HelmetとCookie設定、npm auditの確認を忘れないようにしましょう。
Helmetを入れればExpress.jsのセキュリティ対策は完了ですか?
完了ではありません。
Helmetはセキュリティ関連HTTPヘッダーを設定するための便利なミドルウェアです。
しかし、TLS、Cookie設定、入力検証、依存関係チェック、ログイン試行制限などは別途必要です。
Helmetは重要な対策の一つですが、全体の一部として考えましょう。
Express.jsでCookieを使うときに重要な設定は何ですか?
重要なのは、デフォルトのセッションCookie名を使わないことと、Cookieのセキュリティオプションを設定することです。
公式ドキュメントでは、secure、httpOnly、domain、path、expires などのオプションが紹介されています。
ログイン機能を実装する場合は、Cookie設定を必ず確認しましょう。
npm auditは必ず実行した方がいいですか?
本番公開前には確認することをおすすめします。
Express.js公式ドキュメントでも、npm audit を使って依存関係ツリーを分析できると説明されています。
npmパッケージの脆弱性はアプリ全体に影響する可能性があるため、依存関係チェックは習慣化した方がよいです。
Express.js初心者は何から学べばいいですか?
まだExpress.jsでアプリを作った経験が少ない場合は、まずルーティング、ミドルウェア、リクエスト・レスポンス、Cookie、セッションなどの基本を学ぶのがおすすめです。
そのうえで、本記事のようなセキュリティベストプラクティスを確認すると理解しやすくなります。
基礎から手を動かして学びたい人は、Express.jsやWebアプリ開発の入門書を使うのも選択肢です。
Express.jsのセキュリティ対策は個人開発でも必要ですか?
必要です。
個人開発でも、インターネット上に公開するなら本番環境と同じように攻撃対象になる可能性があります。
特に、ログイン機能、問い合わせフォーム、管理画面、個人情報を扱う機能がある場合は、最低限のセキュリティ対策を確認しておきましょう。
まとめ:Express.jsを本番公開する前にセキュリティ対策を確認しよう
Express.jsはシンプルで使いやすいフレームワークですが、本番環境で安全に使うにはセキュリティ対策が必要です。
この記事では、Express.js公式ドキュメントをもとに、以下の対策を解説しました。
- 非推奨・脆弱なExpress.jsバージョンを使わない
- TLSを使って通信を暗号化する
- ユーザー入力を信頼しない
- open redirectを防ぐ
- HelmetでHTTPヘッダーを設定する
- X-Powered-Byを無効化してフィンガープリントを減らす
- Cookieとセッションを安全に扱う
- ブルートフォース攻撃を防ぐ
- npm auditやSnykで依存関係を確認する
- Webアプリ全体の脆弱性にも注意する
初心者の場合、最初から完璧なセキュリティ対策をするのは難しいです。
ただし、本番公開前に公式ドキュメントのベストプラクティスを確認し、最低限の対策を一つずつ実装していくことが大切です。
Express.jsの基礎がまだ不安な人は、まずは入門書でアプリ開発の流れを学びましょう。
Express.jsでアプリを作れるようになった人は、次にセキュリティ、パフォーマンス、設計の順番で学ぶと、実務でも通用しやすいバックエンド開発力につながります。









