質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

node.js expressのresオブジェクトについて

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 3,107

uroncha

score 40

質問です

node.js + express でWEBサービスを構築しようとしています。
ミドルウェアの引数のresオブジェクトに色んな情報を突っ込んで、サイトに表示しているのですが、resオブジェクトに個人情報やパスワードなどを含めてしまうのは、危険なやり方なんでしょうか?ブラウザ側でresオブジェクトの内容が見えてしまうような事ってあるのでしょうか?

ソースコードのイメージ(内容は適当です)

app.use(function(req, res, next) {
    //SQLでログインユーザー情報を丸ごと取得(パスワード込み)
    sql.select(query, function(err, result){
        res.locals.user = result.rows[0];
    }
    next();
});

app.get("/", function(req, res){
    res.render('index.ejs');  //ユーザーの名前をサイトに表示
});
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

まず危険な箇所と危険ではない箇所を切り分けましょう。

質問文の状況下においてWebサイトにアクセスしたユーザーが持ち帰れるのは、
res.render('index.ejs');の行で出力したHTML文章のみです。

つまり、resオブジェクト自体にどんな危険な情報を格納したとしても、
index.ejs等のテンプレートエンジンが不用意に吐き出さなければ安全は確保されます。

またexpressは内部的にhttpパッケージをラッピングしているだけなので、
reqオブジェクトと、resオブジェクトはユーザーがアクセスする度に作られては破棄されます。

どこか別の場所に保存しておいて、違うユーザー相手に勝手に別ユーザーのパスワードを開示する
…といった意図的に危険な作りにしない限り、勝手に他のユーザーに個人情報が漏れる事はありません。


これはエンジニア側の対策の一つですが、
パスワードのような漏れると非常に困るような情報は、出来るだけ取り出さずに扱う事をオススメします。

例えば、ユーザー登録を行った場合、入力値を元にすぐDBに格納してしまいます。
そして、ログイン処理を受け付ける場合、ユーザーの入力値を元にDBへアクセスし、ユーザー情報が取得出来た事をもってログイン成功とします。

connection.query(`
  SELECT id, name, email
  FROM users
  WHERE password = ?
`, [req.body.password], (error, results, fields) => {
  if (!fields || fields.length === 0) {
    return "ログインに失敗しました";
  }
})

上記のような手法を取ればパスワードの変数を持ち運ぶ事無く使えますので、
こういった手法を使いながら不用意な情報を外に出さないように注意すると、他の箇所で失敗しても外部に漏れる事はありません。


次はそもそものHTMLの送受信に関わるお話です。

HTMLやそのリクエストは、平文のままインターネット回線上を伝わってクライアントとサーバーを行き来するので、
多少知識のあるクラッカーには簡単に盗聴されてしまいます。

参考サイト: SSL/TLS総合解説サイト

というわけで、お客様情報を取り扱う(ログイン認証)ページでは、確実にSSL証明書を導入しましょう。
SSL証明書を導入したWebサイトではリクエストやHTML等の情報が暗号化され、安全に通信することが可能です。
(まぁ、時間をかければ解けない暗号はないので、SSLで暗号化されてるからといってクリティカルな情報をばんばん流しまくるような事はしないでください)

ApacheやNginxといった所謂Webサーバーアプリは簡単にSSLと連携することが可能ですが、
Expressサーバーは手動でこの仕組を導入することになります。

参考サイト: Node.js + Express で SSL を使う - まだプログラマーですが何か?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/28 14:03

    私が欲しい適切なアドバイスをいただきました。
    勉強になりました。
    ありがとうございました。

    キャンセル

+1

Webサービスでパスワードは本当に重要な要素なので、ログイン時のリクエスト以外ではやりとり厳禁です。
HTTPSで暗号化してサーバで受け付けた後はセッションで認証を行いましょう。
更にサーバ側でもDBにSHA256、またはSHA512でハッシュ化して、万が一DBの内容が漏れても大事故に
繋がらないようにしておきます。

レスポンスにパスワードを乗せようとしているということは、ブラウザ側で認証を行わせようとしているのだと
思いますが、認証に限らず、入出力は必ずサーバで実装すべきです。
勿論ユーザビリティを考えてブラウザ側でも入力チェックをするのは良い事ですが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/28 11:37

    いろいろと親切にありがとうございました。
    勉強になりました。

    キャンセル

checkベストアンサー

-1

resに入れるということはブラウザ側に戻すということですから全部見えてしまいますよ。
そういった情報はresに入れて戻すべきではないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/28 13:40 編集

    > uronchaさん
    どのブラウザでも通信の情報は見ようとしれば見れちゃうんですよ。
    ブラウザにもよりますがF12とか押すと色々見えます。
    どうしても戻す必要があるのですか?

    キャンセル

  • 2017/10/28 14:01

    パスワードの判定はサーバー側で行うので、そもそもresに入れる必要はないのですが、fieldを選択するのが面倒くさかったので、レコード全体を代入するやり方をとっていました。どうやらresの内容はすべてブラウザ側に渡ってしまう訳ではなさそうですが、安全面をとってパスワードなどの情報は除いてresに代入するようにしようと思います。

    キャンセル

  • 2017/10/28 21:17

    そういうことだったのですね。
    resオブジェクトをrender以外で使うことはあまりないかと思いますし、その方がいいかと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る