node.js 的小程式後記


修正:
之後提到沒過濾 HTML 的說明是不正確.
因為之前使用了 ejs 模版引擎.原來他已對 HTML 作出了 escape 動作

1
2
<%= something %> 會對輸出的內容進行 HTML 過濾(escape)
<%- something %> 會對輸出的內容如實輸出不過濾(escape)

所以可以免去了另外自寫過濾的函數,如:

1
2
3
4
5
function sanitize(html){
return String(html).replace(/&(?!\w+;)/g, '&amp;')
.replace(//g, '&gt;')
.replace(/"/g, '&quot;');
}

補充:
因為之前用了一個 expressjs 的模組 express-csrf
後來發現這東西會因為 req.flash 產生衝突.
所以發生了傳出的 csrf 值和 session 中保存的 csrf session 值不符
導致了提交失敗的情況.所以最後便決定自己實現這模組解決這情況,記錄如下:

  1. 先移除原先安裝了的 express-csrf 模組
    1
    npm remove express-csrf
  2. 之後在原目錄中建立 library 目錄
  3. 之後再將下面的代碼保存於 library/express-csrf.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var crypto = require('crypto');

    exports.token = function(req, res) {
    if (typeof req.session.csrf === "undefined" || req.session.csrf === null) {
    req.session.csrf = crypto.createHash('md5').update('' + new Date().getTime() + req.session.lastAccess).digest('hex');
    }
    return req.session.csrf;
    };

    exports.check = function() {
    return function(req, res, next) {
    // If request is ajax, no need to check csrf.
    if (req.xhr === false && req.body && req.method.toLowerCase() === 'post') {
    var csrf = req.session.csrf;
    req.session.csrf = null;
    if (req.body.csrf !== csrf) {
    return res.send("Cross-site request forgery attempt discovered!", 403);
    }
    }
    return next();
    };
    };
  4. 之後打開 app.js 修改
    1
    2
    3
    4
    5
    // 原來
    csrf = require('express-csrf');

    // 改為
    csrf = require('./library/express-csrf');
  • 備注