SQL injection in Column name? #6387

Closed
opened 2026-01-22 15:32:12 +01:00 by admin · 10 comments
Owner

Originally created by @sneakyx on GitHub (Jan 16, 2020).

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.

Originally created by @sneakyx on GitHub (Jan 16, 2020). ### 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.
admin closed this issue 2026-01-22 15:32:13 +01:00
Author
Owner

@sneakyx commented on GitHub (Jan 17, 2020):

This works also in 2.7.0

@sneakyx commented on GitHub (Jan 17, 2020): This works also in 2.7.0
Author
Owner

@JoppeDC commented on GitHub (Jan 17, 2020):

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

@JoppeDC commented on GitHub (Jan 17, 2020): I would suspect that this is indeed a bug, but it has no security implications unless you somehow use user input for column names.
Author
Owner

@sneakyx commented on GitHub (Jan 17, 2020):

OK, see your point, I remove the security.

@sneakyx commented on GitHub (Jan 17, 2020): OK, see your point, I remove the security.
Author
Owner

@IonBazan commented on GitHub (Jan 17, 2020):

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.

@IonBazan commented on GitHub (Jan 17, 2020): 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.
Author
Owner

@sneakyx commented on GitHub (Jan 17, 2020):

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.

@sneakyx commented on GitHub (Jan 17, 2020): 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.
Author
Owner

@danabrey commented on GitHub (Jan 17, 2020):

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.

@danabrey commented on GitHub (Jan 17, 2020): 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.
Author
Owner

@sneakyx commented on GitHub (Jan 17, 2020):

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.

@sneakyx commented on GitHub (Jan 17, 2020): 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.
Author
Owner

@JoppeDC commented on GitHub (Jan 17, 2020):

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

@JoppeDC commented on GitHub (Jan 17, 2020): This doesn't look like anything you'd want to do in the annotation
Author
Owner

@sneakyx commented on GitHub (Jan 17, 2020):

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.

@sneakyx commented on GitHub (Jan 17, 2020): 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.
Author
Owner

@beberlei commented on GitHub (Jan 18, 2020):

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.

@beberlei commented on GitHub (Jan 18, 2020): 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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6387