2012-12-28 4 views
2

안녕 얘들 아, 메리 크리스마스!fmdb - SQL 인젝션을 피하는 것과 같은 쿼리를 선택하십시오.

sqlite 및 fmdb를 래퍼로 사용하여 iOS 앱을 제작하고 있습니다. 나는 다음과 같은 SQL 문을 실행하려고하십시오 UISearchBar에서 나오는 텍스트

SELECT * FROM TABLE WHERE FIELD LIKE '%text%' 

합니다.

NSString *query = [NSString stringWithFormat:@"SELECT * FROM TABLE WHERE FIELD LIKE '%%%@%%'", text]; 
FMResultSet *results = [db executeQuery:query]; 

난 단지 쿼리 코드를 게시하고 있습니다 :

이제 유일한 방법까지 나는 다음과 같은 코드로했다 워킹 얻었다. 잘 작동한다.

NSString *query = @"SELECT * FROM TABLE WHERE FIELD LIKE %%?%%"; 
FMResultSet *results = [db executeQuery:query, text]; 

또는 뭔가 같은 :

NSString *query = @"SELECT * FROM TABLE WHERE FIELD LIKE ?"; 
FMResultSet *results = [db executeQuery:query, [NSString stringWithFormat:@"%%%@%%", text]]; 

작동하지 않는 그래도 원하는 것은

는, 내가 좋아하는 뭔가를 시도하고, 그래서 SQL 주입을 방지하는 것입니다. like 절 ('%%? %%') 주위의 작은 따옴표 나 double 대신 단일 %를 사용할 때도 마찬가지입니다.

이 문제를 해결해 줄 수 있습니까? 도움이 될 것입니다.

새해 복 많이 받으세요!

+1

+1 나는 당신이 이것을 올바르게 다루고 있다는 사실을 아주 좋아합니다. 너무 많은 사람들이 우연히 또는 의도적으로 사용자 필드에서 따옴표 문자를 사용하지 않고 사용자 제공 필드를 사용하여'stringWithFormat'을 사용하여 blithely 자신의 SQL을 빌드합니다. 사용자가 제공 한 데이터를 사용할 때마다'? '자리 표시자를 사용해야합니다. 너무 많은 앱에서 조의 "Fish House"를 검색하는 것은 문제가됩니다. – Rob

답변

3

마지막 시도 (따옴표 제외)는 올바른 구문입니다. resultsnil이 아닌지 확인하고 있습니까? nil 인 경우 오류 문자열을 확인해야합니다. 예를 들어,이 작품 :

NSString *searchString = @"larry"; 
NSString *likeParameter = [NSString stringWithFormat:@"%%%@%%", searchString]; 
NSString *sql = @"SELECT text_column FROM test WHERE text_column LIKE ?"; 

FMResultSet *results = [db executeQuery:sql, likeParameter]; 

if (!results) 
{ 
    NSLog(@"error: %@", [db lastErrorMessage]); 
    [db close]; 
    return; 
} 

while ([results next]) 
{ 
    NSLog(@"%s: %@", __FUNCTION__, results[0]); 
} 

[results close]; 
[db close]; 

을 그건 그렇고, 당신은 특정 당하고 당신은 최종 사용자가 직관적 반응을 매개 변수를 조작하거나 받고 싶지 않아 (그리고 당신이 원하지 않는 경우 최종 사용자가 자신의 와일드 카드 문자를 적용하는 경우) 또는 _과 같은 와일드 카드 문자를 ESCAPE SQL 구문을 사용하여 이스케이프 할 수 있습니다. 따라서, 당신은 이스케이프 문자에 대한 상수를 정의 할 수 있습니다 : 당신의 SQL을 구축하고

NSString * const kEscapeCharacter = @"\\"; 

을 그리고 같은 :

NSString *likeParameter = [NSString stringWithFormat:@"%%%@%%", [self escapedLikeParameter:searchString]]; 
NSString *sql = [NSString stringWithFormat:@"SELECT text_column FROM test WHERE text_column LIKE ? ESCAPE '%@'", kEscapeCharacter]; 
escapedLikeParameter% 탈출

, _ 및 와일드 카드 문자 자체. 따라서 :

- (NSString *)escapedLikeParameter:(NSString *)string 
{ 
    NSString *escapedString; 
    escapedString = [string stringByReplacingOccurrencesOfString:kEscapeCharacter 
                   withString:[NSString stringWithFormat:@"%@%@", kEscapeCharacter, kEscapeCharacter]]; 
    escapedString = [escapedString stringByReplacingOccurrencesOfString:@"_" 
                  withString:[NSString stringWithFormat:@"%@_", kEscapeCharacter]]; 
    return [escapedString stringByReplacingOccurrencesOfString:@"%" 
                withString:[NSString stringWithFormat:@"%@%%", kEscapeCharacter]]; 
} 

그런 식으로, 당신은 다중 문자 와일드 카드 문자, /, 또는 단일 문자 와일드 카드 문자, _있는 사람을 포함한 모든 문자열을 검색 할 수 있습니다.

+1

대단히 감사합니다 롭!두 가지 제안 (탈출 여부)이 나를 위해 트릭을합니다! 고맙습니다. – ozzotto

관련 문제