使用ObjC中的NSURLRequest在URL中发送SQL查询

cal*_*nch 1 php sql get objective-c nsurlrequest

尝试使用目标C中的NSURLRequest类传递和SQL查询时,我有一个非常奇怪的问题.我能够发送一个有效的简单查询并返回正确的内容(JSON格式).这是我的代码:

NSString *URLWithSQLQuery = [NSString stringWithString:@"http://localhost/querydatabase.php?query=INSERT+INTO+Table+(ID,Column1,Column2,Column3,Column4,Column5,Column6,Column7,Column8)+VALUES+(NULL,'a','b','','c','d','','1','2')"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLWithSQLQuery]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *data = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(@"%@", data);
Run Code Online (Sandbox Code Playgroud)

这不会将虚拟值插入表中.以下代码返回正确的内容:

NSString *URLWithSQLQuery = [NSString stringWithString:@"http://localhost/querydatabase.php?query=SELECT+*+FROM+Table"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLWithSQLQuery]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *data = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(@"%@", data);
Run Code Online (Sandbox Code Playgroud)

当我粘贴网址http://localhost/querydatabase.php?query = INSERT + INTO + Table +(ID,Column1,Column2,Column3,Column4,Column5,Column6,Column7,Column8)+ VALUES +(NULL,'a' ,'b','','c','d','','1','2')在我的浏览器中,查询正确执行.所以我真的不知道问题出在哪里,因为它不是来自PHP脚本,URLWithSQLQuery也不是来自我的Objective C代码.

任何想法将不胜感激.感谢大家的帮助.

斯科特

mrl*_*lee 13

这个问题已得到解答,但我认为值得指出将来遇到这个问题的任何人,以及问题的海报:

不要通过您的URL发送实际的SQL

这是一个巨大的安全漏洞.没有完全荒谬的卫生和验证,这个代码,当释放到野外时,将使您的服务器和数据库敞开大门.

我将假设您将查询字符串推入mysql_query()或等等,例如:

$query = mysql_query($_GET['query']);
Run Code Online (Sandbox Code Playgroud)

任何找到你的API的人都不需要破解它,因为你已经为他们完成了所有艰苦的工作.这就像建造诺克斯堡,但是打开前门.该建筑可以承受攻击,但任何知道的人都可以走进去.

他们只需要将URL更改为他们喜欢的任何查询:

// Delete one of your databases
http://your-server.com/querydatabase.php?query=DROP+DATABASE+DBNAME

// Create a new user account to log in directly
http://your-server.com/querydatabase.php?query=GRANT+ALL+PRIVILEGES+ON+*.*+TO+'bobby'%40%25+IDENTIFIED+BY+'password'
Run Code Online (Sandbox Code Playgroud)

您的PHP代码需要为要保存的数据采用一系列单独的参数,并且在将它们插入预先构建的SQL查询之前,您需要确保它们是正确且有效的.这严重限制了(但并未阻止所有)不道德的个人利用您的服务器做坏事的机会.

作为一个非常基本的例子(以你已经拥有的风格):

// get records from the database
http://your-server.com/querydatabase.php?query=list

if ($_GET['query'] == 'list') {
    mysql_query("SELECT * FROM TABLE");
}

// you would actually make a POST request to do this
http://your-server.com/querydatabase.php?query=save&column1=value1&column2=value2...

if ($_GET['query'] == 'save') {
    $column1 = mysql_real_escape_string($_GET['column1']);
    $column2 = mysql_real_escape_string($_GET['column2']);

   // only want column 1 to be an integer?
   if (!ctype_digit($column1)) die("Column 1 is not a number");

   mysql_query("INSERT INTO TABLE (column1, column2) VALUES ($column1, $column2)");
}
Run Code Online (Sandbox Code Playgroud)

首选和稍微更先进的方法是抛弃mysql_*和使用mysqliPDO(或ORM,它为你处理所有),所以你可以使用prepared statements.

这似乎并不重要,特别是因为你在localhost上运行它,但问题中证明的是危险的.

  • 无论您如何发送查询,通过HTTP请求发送查询都是危险的. (2认同)