Проверка объекта, если в его полях содержатся операторы SQL - PullRequest
1 голос
/ 03 октября 2019

У меня есть следующая структура объекта 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.

1 Ответ

1 голос
/ 05 октября 2019

В любое время, когда данные должны быть проверены / очищены, я настоятельно рекомендую использовать стороннюю библиотеку. В этом случае вы можете взглянуть на Джой (https://github.com/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) - это сделано только для иллюстрации, обычно этот тип определения повторяющейся схемы объявляется как общая константа и используется повторно.

Поначалу может показаться, что этот подход гораздо более многословен, чем «прямая» проверка вручную, и требует больше работы, чем следует. В действительности, отделение правил проверки от фактического кода делает его гораздо более гибким и поддерживаемым решением - и намноготакже более читабельным. Обычно схемы определяются в собственном общем модуле и импортируютсяредактировать всякий раз, когда необходимо проверить данные.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...