问题描述
大家好!
我想通过将某些特殊字符列入黑名单来阻止我的React Native
应用中的跨站点脚本编写,如果该字符插入到我的RealmDB
中,这将非常危险
我确实阅读了文档,并找到了一些名为.disallow()
,.not()
和.invalid()
的API,
此API仅验证一个字符或一个单词,这意味着如果我在黑名单中插入具有特殊字符的值(如"<script>"
,则验证将通过,但如果我仅插入"<"
,则验证将通过错误,我找不到另一个仅将特殊字符"<"
,">"
,"{"
,"}"
列入黑名单并允许其他所有内容使用的API,我真的希望Joi拥有一个类似于.pattern()
,但相反。我希望有人有一个很酷的自己的方法并与Joi集成在一起,如果在这里分享,那将很有帮助
我在Joi browser中几乎没有示例代码,希望与Joi NodeJS一样。
var dataObj = {
userNotes: '<script>' // "<" and ">" is on the blacklist
};
var validationSchema = {
userNotes: Joi.string().trim().required().invalid('<','>','{','}')
};
Joi.validate(dataObj,validationSchema).then(function(success) {
console.log(success); // Will be success not Error
}).catch(function(error) {
console.error(error)
});
<script src="https://cdn.jsdelivr.net/npm/joi-browser@13.4.0/dist/joi-browser.min.js"></script>
解决方法
自定义验证器很好,但如果您只测试正则表达式,您可以使用 string.pattern
first_name: Joi.string().required().regex(/[$\(\)<>]/,{ invert: true }),
如果您的名字中有 $,(,),<,>
,此规则将引发错误。
如果您省略 { invert: true }
选项,它将要求您在名字中包含 $,>
,而没有人应该这样做。我怀疑这会让某人在 21 世纪及以后的生活变得非常艰难。
文档
https://joi.dev/api/?v=17.3.0#stringpatternregex-name--options---aliases-regex
,仔细阅读文档约2个小时后,我发现了一个名为.custom()
的API,它允许您创建自己的验证以及自定义错误消息。 请记住,它仅适用于Joi NodeJS而不适用于joi浏览器
这里有一些示例代码
import Joi from 'joi';
/**
* Blacklist special character
* "<",">","{","}"
* you can add more just inside "[]" in myRegexPattern
*/
// I use regex for my own Joi validation
// This regex will find anything character inside "[]" in the string
// I don't know it's good or bad Regex
// PLEASE FIX THIS if it's bad Regex
const myRegexPattern = new RegExp(/^.*[<>{}].*$/s);
// This string is very bad for my React Native apps
const userInputValue = "<Button onPress={() => alert('Whoops!')}></Button>";
// Now test it with Joi
const validationSchema = Joi.string().custom((value,helpers) => {
// if true Joi will be throw an error with code "any.invalid"
// The "code" NOT a "message" error
return myRegexPattern.test(value) ? helpers.error('any.invalid') : value
}).messages({
// errorCode: errorMessage
'any.invalid': "Whooaaa! That's a Bad String"
});
// It will be resulting an error and that's what i wan to
// because that input value is soo bad
validationSchema.validateAsync(userInputValue)
.then(success => {
console.log(`Success value: ${success}`);
})
.catch(error => {
console.error(error);
});
如果有人发布了更好的答案,它将很有帮助
,Joi 有内置的验证器,只允许字符串中的字符串和数字。 有关用法示例,请参阅下面的示例架构:
const schema = Joi.object().keys({
firstname: joi.string().alphanum().required(),lastname: joi.string().alphanum(),});
});