[MDEV-24435] UPDATE through a view requires an UPDATE GRANT on columns used for JOIN Created: 2020-12-18  Updated: 2023-04-27

Status: Confirmed
Project: MariaDB Server
Component/s: Authentication and Privilege System, Data Manipulation - Update, Views
Affects Version/s: 10.1, 10.1.47, 10.3.27, 10.5.8, 10.2, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5

Type: Bug Priority: Major
Reporter: Ángel Assignee: Oleksandr Byelkin
Resolution: Unresolved Votes: 0
Labels: upstream-fixed
Environment:

Verified on Debian stable with mariadb versions 10.1, 10.3, 10.5.8 and 10.6 build-36886 (i.e. 2020-12-18)



 Description   

When doing an UPDATE on a JOIN of views, mariadb requires that the user holds the UPDATE privilege on the columns referenced in the ON clause.

Expected behavior: only SELECT should be needed on those columns. The = there are comparison operators, not assignments.

Test setup:

CREATE DATABASE test;
use test;
 
-- Create a couple tables and fill with data
CREATE TABLE items (id INT PRIMARY KEY, name VARCHAR(255) );
CREATE TABLE properties (item INT, value VARCHAR(255) );
 
INSERT INTO items (id, name) VALUES (1, 'ball'), (2, 'pencil'), (3, 'bag');
INSERT INTO properties (item, value) VALUES (1, 'red'), (2, 'black'), (3, 'blue');
 
-- Create a user which can only update the value column, on the real table
CREATE USER 'testuser1'@'%' IDENTIFIED BY 'demo';
GRANT SELECT ON items TO 'testuser1'@'%';
GRANT SELECT ON properties TO 'testuser1'@'%';
GRANT UPDATE (value) ON properties TO 'testuser1'@'%';
 
-- Create views mapping the tables
CREATE VIEW itemview AS SELECT * FROM items;
CREATE VIEW propertyview AS SELECT * FROM properties;
 
-- Create a user which can only update the value column, using the views
CREATE USER 'testuser2'@'%' IDENTIFIED BY 'demo';
GRANT SELECT ON itemview TO 'testuser2'@'%';
GRANT SELECT ON propertyview TO 'testuser2'@'%';
GRANT UPDATE (value) ON propertyview TO 'testuser2'@'%';

Test execution:

# testuser1 can update the real table doing a JOIN
mysql -u testuser1 -pdemo test -e "UPDATE items JOIN properties ON (id=item) SET value='yellow' WHERE name='ball';"
 
# However, testuser2 needs UPDATE right on columns used for joining 
mysql -u testuser2 -pdemo test -e "UPDATE itemview JOIN propertyview ON (id=item) SET value='blue' WHERE name='ball';"
ERROR 1143 (42000) at line 1: UPDATE command denied to user 'testuser2'@'localhost' for column 'item' in table 'propertyview'
 
# Although it works correctly if moving them to the WHERE clause
mysql -u testuser2 -pdemo test -e "UPDATE itemview JOIN propertyview SET value='blue' WHERE name='ball' AND id=item;"

Expected behavior:

The second command should have succeeded, as in the real table ("You need the UPDATE privilege only for columns referenced in an UPDATE that are actually updated. You need only the SELECT privilege for any columns that are read but not modified.").



 Comments   
Comment by Elena Stepanova [ 2021-01-12 ]

Thanks for the report. Reproducible as described.
MTR version of the test case:

CREATE DATABASE db;
USE db;
 
CREATE TABLE items (id INT PRIMARY KEY, name VARCHAR(255) );
CREATE TABLE properties (item INT, value VARCHAR(255) );
 
INSERT INTO items (id, name) VALUES (1, 'ball'), (2, 'pencil'), (3, 'bag');
INSERT INTO properties (item, value) VALUES (1, 'red'), (2, 'black'), (3, 'blue');
 
CREATE VIEW itemview AS SELECT * FROM items;
CREATE VIEW propertyview AS SELECT * FROM properties;
 
# Create a user which can only update the value column, on the real table
CREATE USER 'testuser1'@'%';
GRANT SELECT ON items TO 'testuser1'@'%';
GRANT SELECT ON properties TO 'testuser1'@'%';
GRANT UPDATE (value) ON properties TO 'testuser1'@'%';
 
# Create a user which can only update the value column, using the views 
CREATE USER 'testuser2'@'%';
GRANT SELECT ON itemview TO 'testuser2'@'%';
GRANT SELECT ON propertyview TO 'testuser2'@'%';
GRANT UPDATE (value) ON propertyview TO 'testuser2'@'%';
 
--connect(con1,localhost,testuser1,,db)
UPDATE items JOIN properties ON (id=item) SET value='yellow' WHERE name='ball';
 
--connect(con2,localhost,testuser2,,db)
UPDATE itemview JOIN propertyview SET value='blue' WHERE name='ball' AND id=item;
UPDATE itemview JOIN propertyview ON (id=item) SET value='blue' WHERE name='ball';
 
# Cleanup
--disconnect con1
--disconnect con2
--connection default
DROP USER testuser1@'%';
DROP USER testuser2@'%';
DROP DATABASE db;

10.5 8de233af

mysqltest: At line 30: query 'UPDATE itemview JOIN propertyview ON (id=item) SET value='blue' WHERE name='ball'' failed: 1143: UPDATE command denied to user 'testuser2'@'localhost' for column 'item' in table 'propertyview'

Reproducible on all of MariaDB 5.5-10.6 and MySQL 5.5.
Not reproducible on MySQL 5.6+, possibly fixed within https://bugs.mysql.com/bug.php?id=59957

Generated at Thu Feb 08 09:29:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.