Blog#209: 🔐Node.js Expressでユーザー入力の検証とサニタイズ

209

こんにちは、私はトゥアンと申します。東京からフルスタックWeb開発者です。 将来の有用で面白い記事を見逃さないように、私のブログをフォローしてください。😊

はじめに

ユーザー入力の検証とサニタイズは、ウェブ開発において重要な要素です。これにより、SQLインジェクションやクロスサイトスクリプティング(XSS)といったセキュリティ脆弱性を防ぎ、ユーザーが入力したデータが正確で一貫性があることを確保できます。この記事では、Node.js Expressアプリケーションでユーザー入力の検証とサニタイズを行うさまざまな手法を、人気のあるライブラリ「express-validator」と「sanitize-html」を使って説明します。

ユーザー入力を検証・サニタイズする理由

検証

検証とは、ユーザー入力が特定の基準(データ型、長さ、形式など)を満たしているかどうかをチェックするプロセスです。検証には以下のような理由があります:

  1. データの整合性: 検証によって、ユーザー入力が期待される形式に従っていることが保証され、データの処理や保存が容易になります。
  2. ユーザーエクスペリエンス: 入力が誤っていることに関するフィードバックをユーザーに提供することで、ユーザーは自分のミスを修正し、よりスムーズなエクスペリエンスが得られます。
  3. セキュリティ: 検証は、悪意のある入力をアプリケーションのセキュリティの重要な部分に達する前に拒否することで、セキュリティ脆弱性を防ぐ役割があります。

サニタイズ

サニタイズとは、潜在的に有害なデータを取り除くか変更することで、ユーザー入力をクリーニングするプロセスです。これは、ウェブアプリケーションに悪意のあるコードを注入する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-validatorsanitize-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ルートを追加し、検証ミドルウェアの配列を含めました。

この例では、isLengthisEmailバリデータを使用して、ユーザー名が最低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);

allowedTagsallowedAttributesオプションを指定することで、ユーザー入力で許可されるHTML要素と属性を制御できます。

まとめ

この記事では、Node.js Expressアプリケーションでユーザー入力の検証とサニタイズの重要性について説明しました。express-validatorを使った入力検証と、sanitize-htmlを使った入力サニタイズの方法を示しました。これらの手法を実装することで、ウェブアプリケーションのセキュリティとデータの整合性が大幅に向上します。

最後

いつもお世話になっています。この記事を楽しんで、新しいことを学べたら嬉しいです。😊

今度の記事でお会いしましょう!この記事が気に入ったら、私を応援するために「LIKE」を押して登録してください。ありがとうございました。

NGUYỄN ANH TUẤN

Xin chào, mình là Tuấn, một kỹ sư phần mềm đang làm việc tại Tokyo. Đây là blog cá nhân nơi mình chia sẻ kiến thức và kinh nghiệm trong quá trình phát triển bản thân. Hy vọng blog sẽ là nguồn cảm hứng và động lực cho các bạn. Hãy cùng mình học hỏi và trưởng thành mỗi ngày nhé!

Đăng nhận xét

Mới hơn Cũ hơn