проверить строку запроса только для чтения - PullRequest
4 голосов
/ 09 января 2012

Я создаю программу чтения базы данных postgreSQL, которая также включает метод, позволяющий пользователю вводить собственный запрос. Я хочу защитить базу данных, проверив, содержит ли напечатанный запрос какой-либо модифицирующий код. это мой чек:

    private bool chech_unwanted_text(string query)
    {
        if (query.Contains("DELETE") || query.Contains("delete") || query.Contains("CREATE") || 
          query.Contains("create") || query.Contains("COPY") || query.Contains("copy") || 
          query.Contains("INSERT") || query.Contains("insert") || query.Contains("DROP") || 
          query.Contains("drop") || query.Contains("UPDATE") || query.Contains("update") || 
          query.Contains("ALTER") || query.Contains("alter"))
        {
            return false;
        }
        else return true;
    }

это правильный метод проверки запроса на безопасное редактирование или есть другой, более надежный способ добиться этого?

Я знаю о предоставлении прав пользователям, но это не работает, потому что у меня нет учетной записи суперпользователя.

Ответы [ 5 ]

9 голосов
/ 09 января 2012

Вы должны справиться с этим, используя учетную запись с доступом только для чтения к базе данных, а не проверяя запрос. Большинство СУБД имеют механизм привилегий для обработки подобных вещей, и PostgreSQL, безусловно, делает.

1 голос
/ 10 января 2012

Если вы не можете сделать учетную запись доступной только для чтения, вы все равно можете сделать конкретную транзакцию доступной только для чтения, введя команду SQL SET TRANSACTION READ ONLY сразу после начала транзакции. Тогда любая попытка изменить данные в этой транзакции потерпит неудачу с

ОШИБКА: транзакция только для чтения

1 голос
/ 09 января 2012

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

Рассмотрим этот запрос:

SELECT * FROM myview;

Где myview - этоопределяется следующим образом:

CREATE VIEW myview AS select foo, bar FROM myfunc();
1 голос
/ 09 января 2012

Предоставление пользователям возможности вводить свои собственные запросы никогда не было хорошей идеей.Единственный безопасный способ сделать это - предоставить им права только для чтения (что, как вы сказали, вы не можете сделать).

Что касается вашего фрагмента кода, то лучший способ проверить, содержит ли ваш запрос глагол, - использоватьLINQ:

private readonly string[] verbs = new string[]
   { "delete", "create", "insert", ... };

private bool check_unwanted_text(string query)
{
    // convert to lowercase
    query = query.ToLowerInvariant();

    // can any verb be found in query?
    return verbs.Any(v => query.Contains(v));
}

Но нет, я бы не стал использовать это для очистки SQL.

0 голосов
/ 09 января 2012

Посмотрите на это для более короткого сравнения: Без учета регистра 'Contains (string)'

По сути, сделать сравнение без учета регистра (в противном случае вам потребуется много кода для проверкиразличные версии DeLetE (DELEte и т. д.)

Кроме того, вы можете создать список с запрещенными ключевыми словами и пройтись по нему, возможно, немного чище?

Что произойдет, если пользователю потребуется выполнить запросчто-то с этими ключевыми словами?

SELECT IsDeleted FROM Users;

Может быть, вы можете посмотреть на разрешающие параметры или, возможно, построить свой собственный "построитель запросов" в зависимости от сложности запросов (куча выпадающих списков, основанных на том, что в базе данных?).

Всего несколько предложений.

Но вы должны, если это возможно, следовать предложению о пользователе только для чтения.

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