0

假设我有一个这样的表格:

// 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 Inspector (Chrome: Developer Tools) 中检查select(name="currency")s option,并将第一个选项的值从“EURUSD”更改为“SOMETHING WIRED”,表单将通过,我们将拥有对象:

{
    name: "SOMETHING WIRED"
    id:   1
    ...
}

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

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

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

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

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

4

2 回答 2

1

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

app.post('/add_currency', function(req, res) {
  var curr = req.body.currency;
  if (curr !== 'EURUSD' || curr !== 'GBPUSD' || curr !== 'USDCHF') {
    res.send(400);
  }
});
于 2013-09-28T17:07:36.277 回答
0

所以如果你在谈论安全,你需要在这里调整你的想法。TCP 连接另一端的客户端不受信任。它可能不是真正的网络浏览器。它可能是一个发送精心设计的恶意攻击的程序。不要考虑 UI 限制,要求浏览器为您强制执行,浏览器中的 javascript 正则表达式确保安全输入。这都没有抓住重点。只需在服务器端代码中确定什么构成和不构成有效/安全请求,并使用服务器中的代码强制执行,当请求无效时发送适当的 4XX 响应。

另一种思考方式是尝试使用 HTML/JavaScript 来“防止更改”Web 表单中的值,这就像在您的房子上贴一个牌子,上面写着“窃贼,请敲前门请求进入”。您对非恶意访问者没有好处,并且被实际攻击者完全忽略。

于 2013-09-28T17:07:26.247 回答