Maintained

Unmaintained

Allowing users of your website to communicate with a database can possibly have
security implications that you should be aware of. Databases allow very
powerful commands that not every user of your website should be able to
execute. Additionally the data in your database probably contains information
that should not be visible to everyone with access to the website.

The most dangerous security problem with regard to databases is the possibility
of SQL injections. An SQL injection security hole allows an attacker to
execute new or modify existing SQL statements to access information that he is
not allowed to access.

Neither Doctrine DBAL nor ORM can prevent such attacks if you are careless as a
developer. This section explains to you the problems of SQL injection and how
to prevent them.

A database library naturally falls touches the class of SQL injection security
vulnerabilities. You should read the following information carefully to
understand how Doctrine can and cannot help you to prevent SQL injection.

In general you should assume that APIs in Doctrine are not safe for user input.
There are however some exceptions.

The following APIs are designed to be SAFE from SQL injections:

For Doctrine\DBAL\Connection#insert($table, $values, $types),
Doctrine\DBAL\Connection#update($table, $values, $where, $types) and
Doctrine\DBAL\Connection#delete($table, $where, $types) only the array
values of $values and $where. The table name and keys of $values
and $where are NOT escaped.

Doctrine\DBAL\Query\QueryBuilder#setFirstResult($offset)

Doctrine\DBAL\Query\QueryBuilder#setMaxResults($limit)

Doctrine\DBAL\Platforms\AbstractPlatform#modifyLimitQuery($sql, $limit, $offset) for the $limit and $offset parameters.

Consider ALL other APIs to be not safe for user-input:

Query methods on the Connection

The QueryBuilder API

The Platforms and SchemaManager APIs to generate and execute DML/DDL SQL statements

To escape user input in those scenarios use the Connection#quote() method.

In this scenario an attacker could still pass a username set to ' OR 1 = 1 and create a valid DQL query.
Although DQL will make use of quoting functions when literals are used in a DQL statement, allowing
the attacker to modify the DQL statement with valid literals cannot be detected by the DQL parser, it
is your responsibility.

You should always use prepared statements to execute your queries. Prepared statements is a two-step
procedure, separating SQL query from the parameters. They are supported (and encouraged) for both
DBAL SQL queries and for ORM DQL queries.

Instead of using string concatenation to insert user-input into your SQL/DQL statements you just specify
either placeholders instead and then explain to the database driver which variable should be bound to
which placeholder. Each database vendor supports different placeholder styles:

There is also executeUpdate which does not return a statement but the number of affected rows.

Besides binding parameters you can also pass the type of the variable. This allows Doctrine or the underyling
vendor to not only escape but also cast the value to the correct type. See the docs on querying and DQL in the
respective chapters for more information.