Completing @Virgilio Novic’s reply, what says to documentation of the Doctrine:
In general you should assume that Apis in Doctrine are not safe for user input. There are However some exceptions.
Free translation:
In general, you should assume that the Apis in Doctrine are not safe for user inputs. There are, however, some exceptions.
Exceptions can be seen in the following links:
Notice what the section says 12.2.1. Wrong: String Concatenation (concreteness of strings), you should never build your queries dynamically and concatenate user inputs into your SQL or DQL query. For Doctrine there is absolutely no way to find out which parts of SQL are user inputs and which are not.
For example:
<?php
$sql = "SELECT * FROM users WHERE name = '" . $_GET['username']. "'";
Although DQL is a wrapper around SQL that can protect against some security implications, the previous example is also a threat to DQL queries, which in the end will result in a query:
$dql = "SELECT u FROM User u WHERE u.username = '" . $_GET['username'] . "'";
In this scenario, an attacker can still pass a user name defined as 'OR 1 = 1
and create a valid DQL query.
So, how to make queries safer?
- Prepared Statements: you should always use it to perform your queries. It is a two-step procedure, separating the SQL query from the parameters. They are supported for SQL DBAL queries and DQL ORM queries.
Example DQL:
$dql = "SELECT u FROM User u WHERE u.username = :name";
$query = $em->createQuery($dql);
$query->setParameter("name", $_GET['username']);
$data = $query->getResult();
Example SQL:
$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $connection->executeQuery($sql, array($_GET['username']));
See more information on how to use it here.
- Quoting/Escaping: Although previously said that string concatenation is wrong, there is a way to do it correctly using the method of
Connection#quote
. This method is only available for SQL, not DQL. For DQL it is always encouraged to use Prepared Statements
not only for security, but also for cache reasons.
Example:
$sql = "SELECT * FROM users WHERE name = " . $connection->quote($_GET['username'], \PDO::PARAM_STR);
Data received via Request using Doctrine need to be treated?
Depends on the API being used as referred to in documentation, but in general if the query is being built based on user input, yes, it is necessary to handle all entries.
Thanks Virgilio for the help.. right.. I didn’t really know what I could do, but then I ask you, is it necessary to do this using Doctrine? I hear Doctrine is in charge of filtering the fields that will be saved. Can I be talking nonsense, I do not have much knowledge on the subject.. Can you assist me? Grateful
– Alexandro Zaleski
@Alexandrozaleski, I cannot confirm that the
Doctrine
do it internally, I would have to do the same thing I just did by checking the code of theDoctrine
, But I would do the answer this way, because I would already send Doctrine the most complete data and almost without problems. I use Laravel and I do it myself with Eloquent, I don’t send data without checking,).– novic
Okay.. Thank you very much @Virgilionovic for your help, I think you can never have too much security.. I’m going to use it this way to not depend on Doctrine for validations that need to be done before they’re sent to the right bank? Thank you very much again..
– Alexandro Zaleski
OK @Alexandrozaleski, validating is always good. If you have a Validation between them will already cure most of the problems
– novic
@Virgilionovic excellent tips on Symfony!
– Guilherme Nascimento
Vlw @Guilhermenascimento ... !
– novic