#javascript #react-native #realm #xss #joi
#javascript #react-native #область #xss #joi
Вопрос:
Всем привет!
Я хочу предотвратить межсайтовые скрипты в своих React Native
приложениях, поместив в черный список специальный символ, который слишком опасен, если этот символ вставлен в мой RealmDB
Я читаю документацию и нахожу некоторые API с именами .disallow()
, .not()
и .invalid()
, эти API проверяют только один символ или одно слово, это означает, что если я вставлю значение, имеющее специальный символ в черный список, например, "<script>"
, проверка будет передана, но если я только вставлю "<"
, проверка будет ошибкой, я не могу найти другой API, который заносит в черный список только специальный символ "<"
, ">"
"{"
, "}"
.pattern()
и разрешает все остальное, я действительно надеюсь, что у Joi есть такой API, как,, но это наоборот. Я надеюсь, что у кого-то есть классный собственный метод, интегрированный с 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>
Комментарии:
1. @mplungjan Извините, пример был добавлен сейчас
2. Можете ли вы добавить пример, который не соответствует вашим требованиям? Или вы бы разрешили
<script>
, но не<
3. @mplungjan на самом деле я пытаюсь запретить пользователю вставлять HTML-тег или синтаксис JSON в мой RealmDB, но также я не хочу использовать другой модуль, такой как sanitize-html, если это возможно только с использованием Joi
Ответ №1:
Пользовательские валидаторы хороши, но если вы тестируете только регулярное выражение, вы можете упростить себе жизнь и использовать string.pattern
first_name: Joi.string().required().regex(/[$()<>]/, { invert: true }),
это правило выдаст ошибку, если у вас есть $,(,),<,>
в вашем first_name.
Если вы опустите { invert: true }
параметр, вам потребуется указать $,(,),<,>
в вашем first_name, чего никто не должен. Я подозреваю, что это очень усложнило бы чью-то жизнь в 21 веке и за его пределами.
Документация
https://joi.dev/api/?v=17.3.0#stringpatternregex-name—options—aliases-regex
Ответ №2:
Joi имеет встроенные средства проверки, позволяющие использовать только строки и числа в строке. смотрите пример схемы ниже для примера использования:
const schema = Joi.object().keys({
firstname: joi.string().alphanum().required(),
lastname: joi.string().alphanum(),
});
});
Ответ №3:
Внимательно прочитав документацию в течение примерно 2 часов, я нашел API, который он называется .custom()
, он позволяет вам создавать свою собственную проверку, а также пользовательское сообщение об ошибке. Помните, что это работает только для 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);
});
Если у кого-нибудь есть лучший ответ, просто опубликуйте его, это будет так полезно