Как удалить 'из NSString в запросе sqlite - PullRequest
0 голосов
/ 03 января 2019

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

 NSMutableString *msql = [[NSMutableString alloc] initWithFormat:@"insert into %@ ", tableName];
        for (int i=0; i<[arrArguments count]; i++){
            NSMutableArray *marrArgum = [arrArguments objectAtIndex:i];

            if (i==0){
[msql appendFormat:@"SELECT '%@' AS 'id', '%@' AS 'UserID', '%@' AS 'MessageID', '%@' AS 'ActualMessage', '\%@\' AS 'MessageType', '%@' AS 'MessageIsOld', '%@' AS 'MessageSentBySelf', '%@' AS 'Timestamp', '%@' AS 'MessageRead', '%@' AS 'MessageToUser' ", [marrArgum objectAtIndex:0], [marrArgum objectAtIndex:1], [marrArgum objectAtIndex:2], [marrArgum objectAtIndex:3], [marrArgum objectAtIndex:4], [marrArgum objectAtIndex:5], [marrArgum objectAtIndex:6], [marrArgum objectAtIndex:7], [marrArgum objectAtIndex:8], [marrArgum objectAtIndex:9]];

}
            else{
                [msql appendFormat:@"UNION ALL SELECT '%@', '%@', '%@', '\%@\', '%@', '%@', '%@', '%@', '%@', '%@' ", [marrArgum objectAtIndex:0], [marrArgum objectAtIndex:1], [marrArgum objectAtIndex:2], [marrArgum objectAtIndex:3], [marrArgum objectAtIndex:4], [marrArgum objectAtIndex:5], [marrArgum objectAtIndex:6], [marrArgum objectAtIndex:7], [marrArgum objectAtIndex:8], [marrArgum objectAtIndex:9]];
            }

NSString *sql = [NSString stringWithFormat: @"%@", msql];
DBLog(@"INSERT SQL QUERY: %@", sql);
        METHOD_CALLER;
        int intQcheck = sqlite3_exec(sqliteDB, [sql UTF8String], NULL, NULL, &err);
        DBLog(@"intQcheck = %d", intQcheck);
        if (intQcheck!= SQLITE_OK) {
            if ([self targetAppIsUsingDevProfile])
                NSAssert(0, @"Error in Insertion Query(intQcheck=%d): %@", intQcheck, strMsql);
            success = NO;
        }

Что я пробовал:

NSString *strMsql = [sql stringByReplacingOccurrencesOfString:@"'" withString:@"\'"];

Но это не работает. Вывод все тот же, что и раньше:

i’ll see u you

Пожалуйста, руководство. Спасибо.

1 Ответ

0 голосов
/ 03 января 2019

Почему подготовленные заявления следует отдавать предпочтение

Когда вы сами создаете SQL-запросы в виде строки, они почти всегда содержат части ввода пользователя. Злоумышленник может воспользоваться этим, например, умно изменив семантику запроса, используя ' и, таким образом, получив несанкционированный доступ к данным или уничтожив их.

Это называется SQL-инъекцией и является одним из самых критических рисков безопасности, см. Здесь: https://www.owasp.org/images/7/72/OWASP_Top_10-2017_%28en%29.pdf.pdf

Защита

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

https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28with_Parameterized_Queries.29

Как использовать подготовленные операторы с SQLite и iOS

Подготовленные заявления см. https://www.sqlite.org/c3ref/stmt.html.

Основные шаги:

  • создать подготовленную выписку
  • привязать значения к параметрам
  • запустить SQL
  • уничтожить объект, чтобы избежать утечек ресурсов

Вот простой пример:

-(BOOL)insertValue:(NSString *)value intoDB:(sqlite3 *)db {
    sqlite3_stmt *stmt = NULL;
    NSString *insertStmt = @"insert into SomeTable (sometext) values (?)";
    //create the prepared statement
    if(SQLITE_OK == sqlite3_prepare_v2(db, insertStmt.UTF8String, -1, &stmt, NULL)) {
        //bind values to parameters
        if(SQLITE_OK == sqlite3_bind_text(stmt, 1, value.UTF8String, -1, SQLITE_STATIC)) {
            //run the SQL
            if(SQLITE_DONE != sqlite3_step(stmt)) {
                return NO;
            }
        }
        else {
            return NO;
        }
        //destroy the object to avoid resource leaks
        sqlite3_finalize(stmt);
    }
    else {
        return NO;
    }
    return YES;
}

Для вашего примера строка будет вызываться i'll see u you, например:

sqlite3 *db;
if(SQLITE_OK == sqlite3_open(dbURL.absoluteString.UTF8String, &db)) {
    NSString *someValue = @"i'll see u you";
    if (![self insertValue:someValue intoDB:db]) {
        NSLog(@"insert failed: '%s'", sqlite3_errmsg(db));
    }
    sqlite3_close(db);
}
else {
    NSLog(@"open db failed: '%s'", sqlite3_errmsg(db));
}

Так что здесь использование ' например. от ввода пользователя не может причинить вреда, потому что мы используем подготовленное утверждение.

Демо

Если вы посмотрите на данные в утилите базы данных, то после этого оператора вставки это выглядит так:

screenshot

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