验证对象,如果其字段中包含SQL语句
我具有对象queryParams
的以下结构:
export default interface Query {
select: SelectParam[];
where?: WhereParam[];
orderBy?: OrderByParam[];
}
export interface SelectParam {
field: string;
}
export interface WhereParam {
conditions: ConditionsParam[];
operator?: string;
}
export interface ConditionsParam {
prop: string;
}
export interface OrderByParam {
prop: string;
}
我需要验证其字段,甚至包括嵌套字段或作为对象数组的字段,如果它包含向其中插入的SQL语句。
我正在以这种方式进行验证,我认为它既无效又不动态。是否有更好的方法来进行验证?
const res = queryParams.select.find(i =>
(i.aggregator ? ((i.aggregator.includes('select') && i.aggregator.includes('from')) || i.aggregator.includes('update') || i.aggregator.includes('drop') || i.aggregator.includes('delete')) : false) || // aggregator CRUD
((i.field.includes('select') && i.field.includes('from')) || i.field.includes('update') || i.field.includes('drop') || i.field.includes('delete')) || // field CRUD
(i.type ? ((i.type.includes('select') && i.type.includes('from')) || i.type.includes('update') || i.type.includes('drop') || i.type.includes('delete')) : false) // type CRUD
);
// the same thing for the rest of the fields.
我相信使用:
Object.entries(queryParam).forEach(([key, value]) => {
...
...
...
});
是执行此操作的方法之一,但由于我是Javascript / Typescript世界的新手,因此不确定如何使用它。
回答如下:每次需要验证/清除数据时,我强烈建议您使用第三方库。在这种情况下,您可能想看一看Joi(https://github/hapijs/joi),它具有一组非常可靠的规则,并且在将来需要更改逻辑时非常灵活。
您通常使用Joi的方式,首先要定义“方案”(这是“验证规则”的Joi语言),从“叶”对象一直到根。您的代码可能如下所示:
const prohibitedTerms = ['select', 'from', 'yellow cat']
const orderBySchema = Joi.string().required().invalid(prohibitedTerms)
const conditionsParamSchema = Joi.string().required().invalid(prohibitedTerms)
const selectParamSchema = Joi.string().required().invalid(prohibitedTerms)
const whereParamSchema = Joi.object({
conditions: Joi.array().items(conditionsParamSchema).required(),
operator: Joi.string().optional
})
const querySchema = Joi.object({
select: Joi.array().items(selectParamSchema).required(),
where: Joi.array().items(whereParamSchema).optional(),
orderBy: Joi.array().items(orderBySchema).optional()
})
...
const myData = <something that needs to be validated>
const { error, value } = querySchema.validate(myData)
if (error) {
// Raise alarm about invalid input, possible injection etc.
}
[您可能已经注意到重复Joi.string().required().invalid(prohibitedTerms)
-这样做只是为了说明,通常这种重复模式定义将被声明为一个公共常量并被重用。
起初,似乎这种方法比手工进行“直接”验证更为冗长,并且比实际需要的工作更多。实际上,将验证规则与实际代码分开会使解决方案更加灵活和可维护,并且可读性也更高。通常,架构将在它们自己的共享模块中定义,并在需要检查数据时导入。
希望有帮助!
验证对象,如果其字段中包含SQL语句
我具有对象queryParams
的以下结构:
export default interface Query {
select: SelectParam[];
where?: WhereParam[];
orderBy?: OrderByParam[];
}
export interface SelectParam {
field: string;
}
export interface WhereParam {
conditions: ConditionsParam[];
operator?: string;
}
export interface ConditionsParam {
prop: string;
}
export interface OrderByParam {
prop: string;
}
我需要验证其字段,甚至包括嵌套字段或作为对象数组的字段,如果它包含向其中插入的SQL语句。
我正在以这种方式进行验证,我认为它既无效又不动态。是否有更好的方法来进行验证?
const res = queryParams.select.find(i =>
(i.aggregator ? ((i.aggregator.includes('select') && i.aggregator.includes('from')) || i.aggregator.includes('update') || i.aggregator.includes('drop') || i.aggregator.includes('delete')) : false) || // aggregator CRUD
((i.field.includes('select') && i.field.includes('from')) || i.field.includes('update') || i.field.includes('drop') || i.field.includes('delete')) || // field CRUD
(i.type ? ((i.type.includes('select') && i.type.includes('from')) || i.type.includes('update') || i.type.includes('drop') || i.type.includes('delete')) : false) // type CRUD
);
// the same thing for the rest of the fields.
我相信使用:
Object.entries(queryParam).forEach(([key, value]) => {
...
...
...
});
是执行此操作的方法之一,但由于我是Javascript / Typescript世界的新手,因此不确定如何使用它。
回答如下:每次需要验证/清除数据时,我强烈建议您使用第三方库。在这种情况下,您可能想看一看Joi(https://github/hapijs/joi),它具有一组非常可靠的规则,并且在将来需要更改逻辑时非常灵活。
您通常使用Joi的方式,首先要定义“方案”(这是“验证规则”的Joi语言),从“叶”对象一直到根。您的代码可能如下所示:
const prohibitedTerms = ['select', 'from', 'yellow cat']
const orderBySchema = Joi.string().required().invalid(prohibitedTerms)
const conditionsParamSchema = Joi.string().required().invalid(prohibitedTerms)
const selectParamSchema = Joi.string().required().invalid(prohibitedTerms)
const whereParamSchema = Joi.object({
conditions: Joi.array().items(conditionsParamSchema).required(),
operator: Joi.string().optional
})
const querySchema = Joi.object({
select: Joi.array().items(selectParamSchema).required(),
where: Joi.array().items(whereParamSchema).optional(),
orderBy: Joi.array().items(orderBySchema).optional()
})
...
const myData = <something that needs to be validated>
const { error, value } = querySchema.validate(myData)
if (error) {
// Raise alarm about invalid input, possible injection etc.
}
[您可能已经注意到重复Joi.string().required().invalid(prohibitedTerms)
-这样做只是为了说明,通常这种重复模式定义将被声明为一个公共常量并被重用。
起初,似乎这种方法比手工进行“直接”验证更为冗长,并且比实际需要的工作更多。实际上,将验证规则与实际代码分开会使解决方案更加灵活和可维护,并且可读性也更高。通常,架构将在它们自己的共享模块中定义,并在需要检查数据时导入。
希望有帮助!