Before directly answering the question, it is worth noting that even if all who can do the attacker is to read data that he should not have, which is usually still very bad. Note that using JOIN and SELECT from system tables (for example, mysql.innodb_table_stats ), an attacker starting with SELECT injection and no other knowledge of your database can match your schema and then completely filter all the data that you have in MySQL . For the vast majority of databases and applications, this is already a disastrous security hole.
But for a direct answer to the question: there are several ways that I know with which the MySQL SELECT injection can be used to modify data. Fortunately, all of them require rather unusual circumstances. All of the following injection examples are given relative to the injection request example from the question:
SELECT id, name, message FROM messages WHERE id = $_GET['q']
1. "Folded" or "batch" requests.
The classic injection method, simply introducing all the other expression after it has been entered. As suggested in another answer here , you can set $_GET['q'] to 1; DELETE FROM users; -- 1; DELETE FROM users; -- 1; DELETE FROM users; -- so that the query forms two statements that are executed sequentially, the second of which deletes everything in the users table.
In mitigation
Most MySQL connectors, in particular, including the PHP functions (legacy) mysql_* and (non-debrecated) mysqli_* , do not support complex or batch queries at all, so this attack simply does not work. However, some of them, in particular, include the PHP PDO connector (although support may be disabled for added security ).
2. Using custom functions
Functions can be called from SELECT and change data. If a data modification function was created in the database, you can make it SELECT , for example by passing 0 OR SOME_FUNCTION_NAME() as the value of $_GET['q'] .
In mitigation
Most databases do not contain any user-defined functions, not to mention data changes, and therefore do not offer any opportunity to perform this kind of exploit.
3. Write to files
As described in an article by Muhaymin Dzulfakar (somewhat allegedly named) Advanced MySQL Exploitation , you can use the INTO OUTFILE or INTO DUMPFILE MySQL chooses to dump the result to a file. Since, using UNION , any arbitrary result can be SELECT ed, this allows us to write new files with arbitrary contents anywhere that mysqld can access. Apparently, this can be used not only to change the data in the MySQL database, but also to gain access to the shell on the server on which it is running, for example, by writing a PHP script on the web root and then querying it. if the MySQL server is shared with the PHP server.
In mitigation
Many factors reduce the practical operational effectiveness of this otherwise impressive attack:
- MySQL will never allow you to use
INTO OUTFILE or INTO DUMPFILE to overwrite an existing file and write to a folder that does not exist. This prevents attacks such as creating a .ssh folder with the private key in the mysql user's home directory, and then SSHing or overwriting the mysqld binary itself with the malicious version and waiting for the server to restart. - Any semi-decent installation package will configure a special user (usually named
mysql ) to start mysqld and give that user only very limited permissions. Thus, he should not write most of the places in the file system - and, of course, should not usually do things like write to the webroot web application. - Modern MySQL installations come with
--secure-file-priv by default, preventing MySQL from writing anywhere except the designated import / export of data and thereby make this attack almost completely powerless ... if the server owner did not intentionally disable it. Fortunately, no one will ever be able to completely disable such a security feature, as it will obviously be - ah, donβt worry .
4. Calling the sys_exec() function from lib_mysqludf_sys to run arbitrary shell commands
There is a MySQL extension called lib_mysqludf_sys , which, judging by its stars on GitHub and its quick search , has at least several hundred users. It adds a function called sys_exec that runs shell commands. As noted in # 2, functions can be called from within SELECT ; The consequences are obvious. To quote the source , this feature can be a safety hazard.
In mitigation
Most systems do not have this extension installed.