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

发布于 2025-01-03 18:32:54 字数 1723 浏览 0 评论 0原文

我在尝试使用 Objective 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 代码。

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

斯科特

I have a very weird problem while trying to pass and SQL query using the NSURLRequest class in objective C. I am able to send a simple query that works and returns the right content (JSON formatted).
Here is my code :

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

This does not insert the dummy values into the table.
The following code returns the right content :

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

And when I paste the 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') into my browser, the query is executed properly. So I really don't know where the problem comes from as it does not come from the PHP script or the URLWithSQLQuery nor does it come from my Objective C code.

Any idea would be greatly appreciated. Thanks to all for your help.

Scott

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流绪微梦 2025-01-10 18:32:54

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

不要通过你的 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_* 并使用 mysqli 或 PDO (或者 ORM,它会为您处理所有事情),因此您可以使用 相反,准备好的语句

这可能看起来不重要,特别是因为您在本地主机上运行它,但问题中所演示的是危险

This question has been answered, but I think it's worth pointing something out to anyone who comes across this question in future, as well as the poster of the question:

Don't EVER send actual SQL through your URLs

This is a gigantic security flaw. Without an utterly ridiculous amount of sanitisation and validation, this code, when unleashed into the wild, will leave your server and database wide open to exploit.

I'm going to make the assumption you shove the query string into mysql_query() or whatever, like:

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

Anyone who finds your API doesn't even need to hack it, because you've done all the hard work for them. It's like building Fort Knox but leaving the front door open. The building can withstand an attack, but anyone who knows can just walk in.

They just need to change the URL to whatever query they like:

// 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'

Your PHP code needs to take a series of separate parameters for the data you want to save, and you need to make sure they're sane and valid before you insert them into a pre-built SQL query. This severely limits (but does not prevent all of) the opportunities available to an unscrupulous individual to do something bad with your server.

As a very basic example (in the style of what you already have):

// 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)");
}

The preferred and slightly more advanced method is to ditch mysql_* and use mysqli or PDO (or an ORM, which handles it all for you), so you can use prepared statements instead.

This may seem unimportant, especially since you're running it on localhost, but what is demonstrated in the question is dangerous.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文