<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Louis-Philippe Véronneau - sql</title><link href="https://veronneau.org/" rel="alternate"></link><link href="https://veronneau.org/feeds/tags/sql.atom.xml" rel="self"></link><id>https://veronneau.org/</id><updated>2018-03-17T00:00:00-04:00</updated><entry><title>Minimal SQL privileges</title><link href="https://veronneau.org/minimal-sql-privileges.html" rel="alternate"></link><published>2018-03-17T00:00:00-04:00</published><updated>2018-03-17T00:00:00-04:00</updated><author><name>Louis-Philippe Véronneau</name></author><id>tag:veronneau.org,2018-03-17:/minimal-sql-privileges.html</id><summary type="html">&lt;p&gt;Lately, I have been working pretty hard on a paper I have to hand out at the end
of my university semester for the machine learning class I'm taking. I will
probably do a long blog post about this paper in May if it turns out to be good,
but …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Lately, I have been working pretty hard on a paper I have to hand out at the end
of my university semester for the machine learning class I'm taking. I will
probably do a long blog post about this paper in May if it turns out to be good,
but for the time being I have some time to kill while my latest boosting model
runs.&lt;/p&gt;
&lt;p&gt;So let's talk about something I've started doing lately: creating issues on FOSS
webapp project trackers when their documentation tells people to grant all
privileges to the database user.&lt;/p&gt;
&lt;p&gt;You know, something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;@&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I'd like to say I've never done this and always took time to specify a
restricted subset of privileges on my servers, but I'd be lying. To be honest, I
woke up last Christmas when someone told me it was an insecure practice.&lt;/p&gt;
&lt;p&gt;When you take a few seconds to think about it, there are quite a few database
level &lt;a href="https://mariadb.com/kb/en/library/grant/#database-privileges"&gt;SQL privileges&lt;/a&gt; and I don't see why I should grant them all to a
webapp if it only needs a few of them.&lt;/p&gt;
&lt;p&gt;So I started asking projects to do something about this and update their
documentation with a minimal set of SQL privileges needed to run correctly. The
Drupal project &lt;a href="https://api.drupal.org/api/drupal/INSTALL.mysql.txt/7.x"&gt;does this quite well&lt;/a&gt; and tells you to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DROP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INDEX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TEMPORARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLES&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;databasename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;@&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;IDENTIFIED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When I first reached out to the upstream devs of these projects, I was sure I'd
be seen as some zealous nuisance. To my surprise, everyone thought it was a good
idea and fixed it.&lt;/p&gt;
&lt;p&gt;Shout out to &lt;a href="https://github.com/nextcloud/documentation/issues/648"&gt;Nextcloud&lt;/a&gt;, &lt;a href="https://github.com/mattermost/mattermost-server/issues/8432"&gt;Mattermost&lt;/a&gt; and &lt;a href="https://github.com/kanboard/kanboard/issues/3699"&gt;KanBoard&lt;/a&gt; for taking this
seriously!&lt;/p&gt;
&lt;p&gt;If you are using a webapp and the documentation states you should grant all
privileges to the database user, here is a template you can use to create an
issue and ask them to change it:&lt;/p&gt;
&lt;pre&gt;
Hi!

The installation documentation says that you should grant all SQL privileges to
the database user:

    GRANT ALL PRIVILEGES ON database.* TO 'username'@'localhost' IDENTIFIED BY 'password';

I was wondering what are the true minimal SQL privileges WEBAPP needs to run
properly.

I don't normally like to grant all privileges for security reasons and would
really appreciate it if you could publish a minimal SQL database privileges
list.

I guess I'm expecting something like [Drupal][drupal] does.

    GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON databasename.* TO 'username'@'localhost' IDENTIFIED BY 'password';

At the database level, [MySQL/MariaDB][mariadb] supports:

* `ALTER`
* `CREATE`
* `CREATE ROUTINE`
* `CREATE TEMPORARY TABLES`
* `CREATE VIEW`
* `DELETE`
* `DELETE HISTORY`
* `DROP`
* `EVENT`
* `INDEX`
* `INSERT`
* `LOCK TABLES`
* `REFERENCES`
* `SELECT`
* `SHOW VIEW`
* `TRIGGER`
* `UPDATE`

Does WEBAPP really need database level privileges like EVENT or CREATE ROUTINE?
If not, why should I grant them?

Thanks for your work on WEBAPP!

[drupal]: https://api.drupal.org/api/drupal/INSTALL.mysql.txt/7.x
[mariadb]: https://mariadb.com/kb/en/library/grant/#database-privileges
&lt;/pre&gt;</content><category term="blog"></category><category term="sql"></category><category term="foss"></category></entry></feed>