javascript 如何在node js中清理我的输入值?

jv4diomz  于 2023-06-28  发布在  Java
关注(0)|答案(5)|浏览(104)

我验证了我的Node.js输入,使它们不会为空,但我也想对它们进行消毒。请帮助我如何做到这一点。

req.checkBody('name', 'Name is required!').notEmpty();
req.checkBody('surname', 'Surname is required!').notEmpty();
req.checkBody('username', 'Username is required!').notEmpty();
req.checkBody('password', 'Password is required!').notEmpty();
req.checkBody('password2', 'Passwords do not match!').equals(req.body.password);

var errors = req.validationErrors();

if (errors) {
    res.render('user/register', {
        errors: errors,
        user: null,
        title: 'Register'
    });
}
else {
    var userData = {
        name : req.body.name,
        surname : req.body.surname,
        username : req.body.username,
        password : req.body.password,
        avatar : 'No_person.jpg'
    };
    userController.addUser(req,res,userData);
}
mrfwxfqh

mrfwxfqh1#

  • 对于大多数框架,可以使用sanitize节点模块:
npm install sanitize --save

然后可以使用像:

var sanitizer = require('sanitize')();

 var name = sanitizer.value(req.name, 'string');
 var surname= sanitizer.value(req.surname, 'string');

有关更多信息,请参阅sanitize文档

const express = require('express');
 const { check } = require('express-validator');
 const app = express();

 app.use(express.json())

 app.post('/form', [
   check('name').isLength({ min: 3 }).trim().escape(),
   check('email').isEmail().normalizeEmail(),
   check('age').isNumeric().trim().escape()
 ], (req, res) => {
   const name  = req.body.name
   const email = req.body.email
   const age   = req.body.age
 })

有关更多信息,请参阅express-validatorexpress-sanitize-input文档。

  • 如果您使用的是Hapi,那么您可以使用Joi进行验证和清理。使用Joi,您可以使用其他选项清理变量
validate(value, schema, {escapeHtml: true}, [callback])

有关更多信息,请参阅Joi文档。

  • 如果您不想使用任何第三方模块,并希望使用内置节点进行清理。您可以尝试以下操作:
// For string variables
 str = typeof(str) === 'string' && str.trim().length > 0 ? str.trim() : '';
 // for boolean values
 bool = typeof(bool) === 'boolean' && bool === true ? true : false;
 // for array values
 arr = typeof(arr) === 'object' && arr instanceof Array ? arr : [];
 // for number values
 num = typeof(num) === 'number' && num % 1 === 0 ? num : 0;
 // for objects
 obj = typeof(obj) === 'object' && !(obj instanceof Array) && obj !== null ? obj : {};
stszievb

stszievb2#

实际上,我写了一个包来轻松解决这个问题。你可以在Github上使用它或贡献它。
从这里下载这个包:https://www.npmjs.com/package/string-sanitizer
您可以使用此实用程序包来清理英语以外的其他语言。这个库使用了正则表达式。您可以将字符串转换为URL或文件名友好的字符串。使用案例如下所示

var string = require("string-sanitizer");

string.sanitize("a.bc@d efg#h"); // abcdefgh
string.sanitize.keepSpace("a.bc@d efg#h"); // abcd efgh
string.sanitize.keepUnicode("a.bc@d efg#hক"); // abcd efghক
string.sanitize.addFullstop("a.bc@d efg#h"); // abcd.efgh
string.sanitize.addUnderscore("a.bc@d efg#h"); // abcd_efgh
string.sanitize.addDash("a.bc@d efg#h"); // abcd-efgh
string.sanitize.removeNumber("@abcd efgh123"); // abcdefgh
string.sanitize.keepNumber("@abcd efgh123"); // abcdefgh123
string.addFullstop("abcd efgh"); // abcd.efgh
string.addUnderscore("@abcd efgh"); // @abcd_efgh
string.addDash("@abcd efgh"); // @abcd-efgh
string.removeSpace("@abcd efgh"); // @abcdefgh

Codeblock

mo49yndu

mo49yndu3#

validator每周有500万次下载,似乎是目前业界最受欢迎的软件包。express-validator使用validator作为其核心。这些当然是一个选择,其他包如xsssanitize-html也是如此
关于这两个验证程序包都有大量的文档,这里是关于清理的部分:
https://express-validator.github.io/docs/sanitization.html

zpqajqem

zpqajqem4#

我使用Yup进行验证。这是一个小得多的包比Joi。我在前端和后端都使用了Yup,我通常将验证放入一个共享的npm包中,前端和后端项目都可以拥有相同的验证库

npm install -S yup

然后

import * as yup from 'yup';

let schema = yup.object().shape({
  name: yup.string().required(),
  age: yup.number().required().positive().integer(),
  email: yup.string().email(),
  website: yup.string().url(),
  createdOn: yup.date().default(function () {
    return new Date();
  }),
});

// check validity
schema
  .isValid({
    name: 'jimmy',
    age: 24,
  })
  .then(function (valid) {
    valid; // => true
  });

Yup的网站:
Yup是一个用于值解析和验证的JavaScript模式构建器。定义架构、转换值以进行匹配、验证现有值的形状,或同时执行这两项操作。是的,模式非常有表现力,允许对复杂的、相互依赖的验证或值转换进行建模。
Yup的API深受Joi的启发,但更精简,并将客户端验证作为其主要用例。Yup将解析和验证功能分离到单独的步骤中。cast()转换数据,而validate检查输入是否是正确的形状。每一个都可以一起执行(例如HTML表单验证)或单独执行(例如反序列化来自API的受信任数据)。
您可能希望为特殊项目(如密码匹配等)创建自己的验证器。这可以使用regex来完成,然后将函数添加到Yup中,如下所示:

let schema = string().matches(/(hi|bye)/);

把所有的验证函数放到你的共享NPM包中(包括你的类型脚本类型等)。前端团队与后端的验证不同步的情况现在将不那么令人担忧。

e4yzc0pl

e4yzc0pl5#

您可以创建自定义中间件,可以集成到任何端点(或全局地针对每个请求),它将检查请求body中的任何输入是否有问题。
它将检查是否:

  • 输入包含一些嵌入的HTML代码(例如图像脚本)。
  • 第一个非白色字符是=,这使得Excel导入容易受到攻击。
    中间件
const containsHtml = /<[^>]*>/;
const startsWithEqual = /^\s*=/;

const isInvalidInput = (input) => {
  return containsHtml.test(input) || startsWithEqual.test(input);
}

exports.inputValidator = (req,res,next) => {
  let invalid_input_count = 0;
  const obj = req.body;
  const stack = [obj];
  while (stack?.length > 0) {
    const currentObj = stack.pop();
    Object.keys(currentObj).forEach(key => {
      if (typeof currentObj[key] === 'object' && currentObj[key] !== null) {
        stack.push(currentObj[key]);
      } else {
        if (typeof currentObj[key] === 'string' && isInvalidInput(currentObj[key])) {
          invalid_input_count++;
        }
      }
    });
  }

  if(invalid_input_count === 0) {
    return next();
  } else{
    return res.status(400).json({ success: false, error_code: 'invalid_input'});
  }
}

用法

const express = require('express');
const { inputValidator } = require('./util/input-validator');

...

const app = express();
app.use(inputValidator); // Check every request for vulnerable inputs

相关问题