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

Posted

技术标签:

【中文标题】在 ObjC 中使用 NSURLRequest 在 URL 中发送 SQL 查询【英文标题】:Sending SQL query in URL using NSURLRequest in ObjC 【发布时间】:2012-02-08 20:59:25 【问题描述】:

我在尝试使用目标 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);

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

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);

当我将 url 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 代码。

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

斯科特

【问题讨论】:

没关系,我的 URL 字符串是一个带格式的字符串,它使用了其他包含空格的字符串,我需要用“+”替换那些空格。无论如何,谢谢。 我更改了它,现在使用 POST 方法而不是 URL 【参考方案1】:

这个问题已经回答了,但我认为值得向将来遇到这个问题的任何人指出一些东西,以及问题的发布者:

永远不要通过 URL 发送实际的 SQL

这是一个巨大的安全漏洞。如果没有完全荒谬的清理和验证,这段代码在被释放到野外时,会让你的服务器和数据库大范围地被利用。

我将假设您将查询字符串推入mysql_query() 或其他任何内容,例如:

$query = mysql_query($_GET['query']);

任何找到您的 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'

您的 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)");

首选且稍微更高级的方法是放弃 mysql_* 并使用 mysqliPDO(或 ORM,它会为您处理这一切),因此您可以改用 prepared statements

这可能看起来并不重要,特别是因为您在 localhost 上运行它,但问题中展示的是危险

【讨论】:

+1 表示不这样做 - 这就是服务存在的原因 - 以抽象和保护您的存储 通过 POST 发送查询是否危险?我只是将其用作使用我的程序填写数据库的工具,仅此而已。无法从 Internet 访问 php 页面。 PS:我正在使用 PDO 通过 HTTP 请求发送查询无论如何都是危险的。

以上是关于在 ObjC 中使用 NSURLRequest 在 URL 中发送 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

NSURLRequest 超时 IOS

除了使用初始化程序之外,如何在 10 秒后停止 NSURLRequest 超时?

在同一个 NSURLRequest 中发送 JSON 数组和 UIImageView

如何在 Swift 中检索 NSURLRequest 的 HTTPBody 参数到 Dictionary: [NSObject: AnyObject]

是否可以防止 NSURLRequest 在请求后缓存数据或删除缓存的数据?

更改为WKWebView后在NSURLRequest上缺少一些cookie