Orm: SQL injection in Column name?

Created on 16 Jan 2020  路  10Comments  路  Source: doctrine/orm

Bug Report

| Q | A
|------------ | ------
| BC Break | yes
| Version | 2.6.3

Summary

Maybe I found an bug.

Current behavior

First I wanted to get an boolean value if a column has a specific value, like
if id_subtype=6 then true, otherwise false, so I tried

/**
     * @Groups({"api_read", "api_write"})
     * @ORM\Column(name="id_subtype=6",type="boolean",nullable=true)
     */
    protected $thisIsTheRightSubType;

This worked, but I can't find this documented, so maybe this is an bug.
I also tried to tried some SQL-injection:

/**
     * @Groups({"api_read", "api_write"})
     * @ORM\Column(name="id_subtype FROM table1 AS a0_; TRUNCATE table2; SELECT a0_id_subtype",type="boolean",nullable=true)
     */
    protected $thisIsTheRightSubType;

table2 is now empty, so SQL- injection works this way.

How to reproduce

See above.

Expected behavior

No SQL query should be executable.

Most helpful comment

I think it is not Doctrine's job to prevent you from hurting yourself so column names are used as-is:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html#quoting-reserved-words
It is too much effort to sanitize developer's input for column mapping.

All 10 comments

This works also in 2.7.0

I would suspect that this is indeed a bug, but it has no security implications unless you somehow use user input for column names.

OK, see your point, I remove the security.

I think it is not Doctrine's job to prevent you from hurting yourself so column names are used as-is:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html#quoting-reserved-words
It is too much effort to sanitize developer's input for column mapping.

Well, my first intension was to ask if this is a bug or a feature and to ask if it this "feature" stays available, because for a special requirement I would like to use
* @ORM\Column(name="id_subtype=6",type="boolean",nullable=true)
But then I tried this sql-injection.

SQL injection is usually from a user, not the developer themselves.

Do you actually want the column to be named "id_subtype=6"? If so, surrounding with backticks might do the trick. Otherwise, I'm not sure what you're trying to achieve here.

I wanted to get a true/false on an mysql database column if there is a specific value in it.
And yes, it works with MySQL, didn't try with other DBMS.

This doesn't look like anything you'd want to do in the annotation

Usually I wouldn't do it, too.
But I removed a column, because it was tautologous. For backwards compability (this is an API with the api platform bundle) I wanted to offer the old column. So, I created this function:

/** * @Groups({"api_read"}) * @return mixed */ public function getThisIsTheRightSubType() { if ($this->getIdSubtype()===6){ return true; } else { return false; } }
But a api-filter doesn't work on it- so I got this wired idea. I know now that it isn't supposed to work that way, but isn't it always the thing with some bugs?
I can think for example of an installation of a composer package installed with some code injected like DROP table xy;
For me (and my colleagues) it feels like a security bug.

This is not SQL injection and not a bug, because that would require the column to be user input. But its developer input. This is through several layers of metadata, but essentially what you are making an argument for is that it would be a security bug if a developer used DBAL like this:

$connection->executeQuery('SELECT id_subtype FROM table1 AS a0_; TRUNCATE table2; SELECT a0_id_subtype');

But essentially it is the will of the developer to do this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

doctrinebot picture doctrinebot  路  3Comments

doctrinebot picture doctrinebot  路  4Comments

alexander-schranz picture alexander-schranz  路  3Comments

delboy1978uk picture delboy1978uk  路  3Comments

doctrinebot picture doctrinebot  路  4Comments