🔐Node.js Expressでユーザー入力の検証とサニタイズ
はじめに
ユーザー入力の検証とサニタイズは、ウェブ開発において重要な要素です。これにより、SQLインジェクションやクロスサイトスクリプティング(XSS)といったセキュリティ脆弱性を防ぎ、ユーザーが入力したデータが正確で一貫性があることを確保できます。この記事では、Node.js Expressアプリケーションでユーザー入力の検証とサニタイズを行うさまざまな手法を、人気のあるライブラリ「express-validator」と「sanitize-html」を使って説明します。
ユーザー入力を検証・サニタイズする理由
検証
検証とは、ユーザー入力が特定の基準(データ型、長さ、形式など)を満たしているかどうかをチェックするプロセスです。検証には以下のような理由があります:
- データの整合性: 検証によって、ユーザー入力が期待される形式に従っていることが保証され、データの処理や保存が容易になります。
- ユーザーエクスペリエンス: 入力が誤っていることに関するフィードバックをユーザーに提供することで、ユーザーは自分のミスを修正し、よりスムーズなエクスペリエンスが得られます。
- セキュリティ: 検証は、悪意のある入力をアプリケーションのセキュリティの重要な部分に達する前に拒否することで、セキュリティ脆弱性を防ぐ役割があります。
サニタイズ
サニタイズとは、潜在的に有害なデータを取り除くか変更することで、ユーザー入力をクリーニングするプロセスです。これは、ウェブアプリケーションに悪意のあるコードを注入するXSS攻撃など、セキュリティ脆弱性を防ぐために重要です。
Expressとミドルウェアの基本
検証とサニタイズに入る前に、まずは基本的なExpressアプリケーションを設定し、ミドルウェアの役割を理解しましょう。
Expressの設定
まず、プロジェクト用の新しいディレクトリを作成し、npmで初期化します:
mkdir node-validation
cd node-validation
npm init -y
次に、Expressをインストールします:
npm install express
新しいファイル「app.js」を作成し、基本的なExpressアプリケーションを設定します:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('こんにちは、世界!');
});
app.listen(3000, () => {
console.log('サーバーがポート3000でリッスンしています');
});
ミドルウェア
Expressでは、ミドルウェアはリクエストオブジェクト、レスポンスオブジェクト、およびリクエスト-レスポンスサイクル内の次の関数にアクセスできる関数です。ミドルウェアはコードを実行し、リクエストおよびレスポンスオブジェクトを変更することができます。
ユーザー入力の検証とサニタイズには、express-validator
とsanitize-html
ライブラリが提供するミドルウェアを使用します。
express-validatorを使った入力検証
express-validator
は、Express
アプリケーションでユーザー入力の検証とサニタイズを行うための人気のあるライブラリです。インストールしてみましょう:
npm install express-validator
基本的な検証
では、ユーザー名とメールアドレスを受け入れるシンプルなフォームを作成してみましょう。app.js
ファイルを以下のように更新します:
const express = require('express');
const { body, validationResult } = require('express-validator');
const app = express();
app.use(express.urlencoded({ extended: false }));
app.post('/submit', [
body('username').isLength({ min: 5 }).withMessage('ユーザー名は5文字以上である必要があります'),
body('email').isEmail().withMessage('メールアドレスは有効な形式である必要があります'),
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
res.send('フォームが正常に送信されました');
});
app.listen(3000, () => {
console.log('サーバーがポート3000でリッスンしています');
});
ここでは、express-validator
からbody
関数をインポートし、リクエストボディに検証ルールを適用するために使用しています。validationResult関数は、検証プロセスの結果を収集するために使用されます。また、フォームの送信用に新しいPOSTルートを追加し、検証ミドルウェアの配列を含めました。
この例では、isLength
とisEmail
バリデータを使用して、ユーザー名が最低5文字であることと、メールが有効な形式であることをチェックしています。また、withMessage
メソッドを使用して、カスタムエラーメッセージを追加しています。
フォームが送信されると、検証ミドルウェアが入力を処理し、エラーをerrorsオブジェクトに追加します。エラーがある場合は、400 Bad Requestステータスとエラーメッセージを返します。検証が成功した場合は、送信されたデータの処理に進みます。
カスタムバリデータ
body
メソッドに関数を提供することで、カスタムバリデータを作成することもできます。例えば、ユーザー名に数字が含まれていないことをチェックするカスタムバリデータを作成してみましょう:
body('username').custom((value) => {
if (/\d/.test(value)) {
throw new Error('ユーザー名には数字を含めないでください');
}
return true;
}),
このカスタムバリデータを、/submit
ルートの検証ミドルウェア配列に追加します。これで、ユーザー名に数字が含まれている場合はフォームの送信が拒否されます。
sanitize-htmlを使った入力サニタイズ
sanitize-html
は、HTML入力のサニタイズに人気のあるライブラリであり、XSS攻撃を防ぐのに役立ちます。まず、このライブラリをインストールしましょう:
npm install sanitize-html
基本的なサニタイズ
では、ユーザーの名前とコメントを受け入れるシンプルなフォームを作成しましょう。app.js
ファイルを以下のように更新します:
const express = require('express');
const sanitizeHtml = require('sanitize-html');
const app = express();
app.use(express.urlencoded({ extended: false }));
app.post('/comment', (req, res) => {
const sanitizedComment = sanitizeHtml(req.body.comment);
res.send(`受け取ったコメント:${sanitizedComment}`);
});
app.listen(3000, () => {
console.log('サーバーがポート3000でリッスンしています');
});
この例では、sanitizeHtml
関数を使ってユーザーのコメントから悪意のあるHTMLをクリーニングしてから処理しています。デフォルトでは、sanitize-html
はホワイトリストに登録されていないHTMLタグをすべて削除し、悪意のあるスクリプトの実行を防ぎます。
カスタムサニタイズオプション
sanitizeHtml
関数にオプションオブジェクトを提供することで、サニタイズの動作をカスタマイズできます。例えば、基本的なテキストフォーマットタグのみを許可し、すべての属性を削除しましょう:
const sanitizeOptions = {
allowedTags: ['b', 'i', 'em', 'strong', 'u'],
allowedAttributes: {},
};
const sanitizedComment = sanitizeHtml(req.body.comment, sanitizeOptions);
allowedTags
とallowedAttributes
オプションを指定することで、ユーザー入力で許可されるHTML要素と属性を制御できます。
まとめ
この記事では、Node.js Express
アプリケーションでユーザー入力の検証とサニタイズの重要性について説明しました。express-validatorを使った入力検証と、sanitize-html
を使った入力サニタイズの方法を示しました。これらの手法を実装することで、ウェブアプリケーションのセキュリティとデータの整合性が大幅に向上します。
Mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.
Donate mình một ly cafe hoặc 1 cây bút bi để mình có thêm động lực cho ra nhiều bài viết hay và chất lượng hơn trong tương lai nhé. À mà nếu bạn có bất kỳ câu hỏi nào thì đừng ngại comment hoặc liên hệ mình qua: Zalo - 0374226770 hoặc Facebook. Mình xin cảm ơn.
Momo: NGUYỄN ANH TUẤN - 0374226770
TPBank: NGUYỄN ANH TUẤN - 0374226770 (hoặc 01681423001)
All rights reserved