0

I have an iOS application which has an array of ID's. These ID's are all numbers:

var ids = [Int]() //Id array in my TableView
ids = basketStruct.getAllIds() //Pulling the array of ID's from my basket model.
print("This is how PHP sees the POST") //Debugging purposes
print(self.ids)
print("This is how PHP sees the POST")
basketServer.ids = self.ids //Passing the ID's to my URLSession.

The URLSession handles the array in the following way:

var ids = [Int]()
func downloadItems() {
    request.httpMethod = "POST"
    let postParameters = "ids="+String(describing: ids)
}

I've refrained from posting anymore of the URLSession class as it's probably unnecessary.

Now My XCode console is as follows:

This is how PHP sees the POST
[1,5,7,8]
This is how PHP sees the POST
Data downloaded
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}

I get no results returned. However, If I change all of my ID arrays to the type NSArray and run, I get results returned, as long as my array contains just 1 ID. The second I add more than 1 ID to the array I get the same error.

Now, over on my php, if I change everything to GET rather than POST and directly enter some values in my URL bar and go to the page in a browser, everything works as it should. I get a nice JSON format response with all the ID's listed in my URL bar.

If I change everything back to POST, then access my apache error log files after trying to run my app, they say the following:

[Thu Feb 22 20:51:42.873663 2018] [:error] [pid 18793] [client 192.168.1.46:60790] PHP Fatal error:  Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[1])' at line 1 in /var/www/api/DbOperation.php:92\nStack trace:\n#0 /var/www/api/DbOperation.php(92): PDO->prepare('SELECT * FROM `...')\n#1 /var/www/api/Basket.php(14): DbOperation->basket('[1, 5, 7, 8]')\n#2 {main}\n  thrown in /var/www/api/DbOperation.php on line 92

I know this problem is broad and consists of many parts, but I'm stuck :( Any help would be much appreciated.

Thanks

P.S - Incase anybody wants to see it, here is my PHP code:

This is the PHP page my URLSession goes too:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
require_once dirname(__FILE__) . '/DbOperation.php';

$ids = $_POST["ids"];

$db = new DbOperation();
$json = $db->basket($ids);

}

Here is DbOperation:

    public function basket($ids) {
    require dirname(__FILE__) .  '/../../dbconnect.php';
    $sql = "SELECT * FROM `Menu` WHERE `ID` IN ($ids)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $result = $stmt->fetchAll();
    echo json_encode($result);
}

1 Answer 1

1

In the PHP exception output you can see that the basket function is called with a string like this:

DbOperation->basket('[1, 5, 7, 8]')

Therefore, the PHP code will generate this SQL:

$sql = "SELECT * FROM `Menu` WHERE `ID` IN ($ids)";

Which is:

SELECT * FROM `Menu` WHERE `ID` IN ([1, 5, 7, 8])

This is not valid SQL.

You can make this work by converting the $ids string into a format that will work in SQL.

// Remove '[' and ']' characters
$inValues = str_replace(['[',']'], '', $ids);
$sql = "SELECT * FROM `Menu` WHERE `ID` IN ($inValues)";

Now you will get:

SELECT * FROM `Menu` WHERE `ID` IN (1, 5, 7, 8)
Sign up to request clarification or add additional context in comments.

2 Comments

This is vulnerable to SQL injections.
I love you. I understand the point from ishegg, I was already aware this was open to an injection attack, I just couldn't understand why it wasn't working as expected. I will mark you as the answer. Thankyou for such a clear explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.