快递 - 防止客户端的表单更改

时间:2013-09-28 16:58:31

标签: node.js security express xss client-side-validation

假设我有一个这样的形式:

// JADE
form(action="", method="POST")
    select(name="currency")
        option(value="EURUSD") EURUSD
        option(value="GBPUSD") GBPUSD
        option(value="USDCHF") USDCHF
    input(type="submit")

# CoffeeScript
sanitizer = require "any sanitizer" # to replace <,>,',", etc.
app.post "/add_currency", (req,res)->
    # I use Sequelize for storing data in MySQL
    Currency.create(
        name: santizer ( req.body.currency )
    ).success( (created_currency)->

    )    

好的,我们会得到一个对象:

{
    name: "EURUSD"
    id:   1
    ...
}

但是,如果我们在浏览器中加载表单,请在Web检查器(Chrome:开发人员工具)中检查select(name="currency")的{​​{1}},并将第一个选项的值从“EURUSD”更改为“SOMETHING WIRED” ,表格将通过,我们将有对象:

option

...假设事实,我们在技术上用消毒剂过滤了我们的输入!所以,问题是:

1。如何防止改变输入的预定值?

2。如何防止更改输入的名称?

我写了一个简单的库来检查select中的select值是否是发送给客户端的 in values数组,但是很难管理。为防止表单名称发生变化,请检查发送的输入名称数组是否完全与从客户端获取的数据相同。

P.S。另一种解决方案可能是使用预定义的数据库字段,只接受几个值。但是,它不是Grail'因为选项列表可能是从实际数据库对象动态生成的。

2 个答案:

答案 0 :(得分:1)

您从客户端收到的任何内容都可能是假的,因此您无法阻止客户端更改输入的名称和预定义值。为了确保您必须在服务器端进行验证,尽管您可以使用客户端JavaScript来使客户端更改表单数据的过程更加困难。

app.post('/add_currency', function(req, res) {
  var curr = req.body.currency;
  if (curr !== 'EURUSD' || curr !== 'GBPUSD' || curr !== 'USDCHF') {
    res.send(400);
  }
});

答案 1 :(得分:0)

如果你在谈论安全问题,那么你需要在这里调整你的想法。 TCP连接另一端的客户端不受信任。它可能不是一个真正的Web浏览器。它可能是一个发送精心制作的恶意攻击的程序。不要在UI限制方面考虑,要求浏览器为您强制执行,浏览器中的javascript正则表达式确保安全输入。这一切都忽略了这一点。只需在服务器端代码中建立有效/无效的请求,并使用服务器中的代码强制执行该请求,并在请求无效时发送相应的4XX响应。

另一种想到它的方法是,尝试使用HTML / JavaScript来“防止改变”网络表单中的值就像在你的房子上注册“窃贼,请敲门前请求进入”。你是否对抗非恶意访问者并不好,并且被实际的攻击者完全忽视。