(core) prevent cross-talk via cache when applying access control to tables

Summary: This fixes a bug where one client's access control limits could remove data from others via a cache.

Test Plan: added test

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2748
This commit is contained in:
Paul Fitzpatrick 2021-03-05 12:12:17 -05:00
parent 48e90c4998
commit 92ef1f400c

View File

@ -10,6 +10,7 @@ import * as bluebird from 'bluebird';
import {EventEmitter} from 'events'; import {EventEmitter} from 'events';
import {IMessage, MsgType} from 'grain-rpc'; import {IMessage, MsgType} from 'grain-rpc';
import * as imageSize from 'image-size'; import * as imageSize from 'image-size';
import cloneDeep = require('lodash/cloneDeep');
import flatten = require('lodash/flatten'); import flatten = require('lodash/flatten');
import remove = require('lodash/remove'); import remove = require('lodash/remove');
import zipObject = require('lodash/zipObject'); import zipObject = require('lodash/zipObject');
@ -635,7 +636,8 @@ export class ActiveDoc extends EventEmitter {
// If row-level access is being controlled, filter the data appropriately. // If row-level access is being controlled, filter the data appropriately.
// Likewise if column-level access is being controlled. // Likewise if column-level access is being controlled.
if (this._granularAccess.getReadPermission(tableAccess) !== 'allow') { if (this._granularAccess.getReadPermission(tableAccess) !== 'allow') {
await this._granularAccess.filterData(docSession, data!); data = cloneDeep(data!); // Clone since underlying fetch may be cached and shared.
await this._granularAccess.filterData(docSession, data);
} }
this.logInfo(docSession, "fetchQuery -> %d rows, cols: %s", this.logInfo(docSession, "fetchQuery -> %d rows, cols: %s",
data![2].length, Object.keys(data![3]).join(", ")); data![2].length, Object.keys(data![3]).join(", "));