The past couple of days, I’ve read through a lot of resources on the sanitization of input and output data with PHP to prevent (most prominently) XSS and SQL injection, i.a. a bunch of question on SO. At this point, however, I feel like I am more confused and insecure about what I am supposed to do and what I am not supposed to do due in part to some contrary information, e.g. I've read many times that I don't need to use mysqli_real_escape_string
or any other forms of sanitization of input whatsoever if I use prepared statements, other sources say I should just use it anyway or even that I should sanitize it like so; this page by Apple rather roughly(?) goes over the topic; etc. Therefore, I would really appreciate some clarification on what I am supposed to do - preferably but not necessarily, by someone who has got some experience in the field (server-side security) due to e.g. working in this field, having done a lot of research in it or maybe even being on the attacker’s side(?).
To understand my situation better, I am going to go over it as concisely as possible:
I am currently programming an app using Swift (iOS) and need to send some data to my server where it is saved in a table using SQL and can be retrieved from by other users (e.g. for a blog).
To do this I send the data via POST, encoded as JSON, to my server (“myphp.php”; with Alamofire, which shouldn’t be very important, though) and decode it there. And this is the first spot where I am not sure if I should already sanitize my data in some way (with reference to the question I linked above). Anyway, then I go on to e.g. insert it in a table using prepared statements (MySQL, so nothing’s emulated). Moreover, I would also like the data I output to be usable in html or rather the entire PHP be usable for AJAX, too.
Here is an example of what I mean:
// SWIFT
// set parameters for request
let parameters: Parameters = [
“key”: “value”,
...
]
// request with json encoded parameters
Alamofire.request(“myphp.php”, method: .post, parameters: parameters, encoding: JSONEncoding.default)
.validate().responseJSON(completionHandler: { (response) in
// do things with data (e.g. show blog post)
// PHP
header('Content-Type: application/json');
$decodedPost = json_decode(file_get_contents('php://input'), true);
// what to do with input...?
// PREPARED STATEMENTS: insert, select, etc.
// what to do with output...?
// echo response - json-encoded so that
// json completion handler in swift can work with it
echo json_encode($output, JSON_NUMERIC_CHECK);
I've asked a friend for some advice on this and he told me he always does the following (xss_clean()
is a function he sent me, too) - whether the data is in- or outputted:
$key = xss_clean(mysqli_real_escape_string($db, trim(htmlspecialchars($data))));
// e.g. $data = decodedPost["key"]
However, not only my research tells me that this probably isn't necessary, but he also told me this has its limitations, most obviously when data is supposed to be retrieved again from the server and displayed again to e.g. another user - as close to the original input as possible.
As you can see, I am really confused. I want to protect the data of users, which is sent to the server, as well as I can so this is a very important topic for me. I hope this question isn't too broad but many other questions were, like I said, either, at least partly, contradictory or very old and e.g. still using simple mysql
extensions and no prepared statements.
If you need more information, feel free to ask. References to official documents (to support answers) are very much appreciated. Thank you!