#3018 closed Defect (fixed)
Memcache bypasses access restrictions
| Reported by: | miguel | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Elgg 1.8.9 |
| Component: | Core | Version: | 1.7 |
| Severity: | critical | Keywords: | security, access restrictions, memcache |
| Cc: | brett@…, steve@…, iamjanek@… | Difficulty: |
Description (last modified by cash)
With memcache active, the function get_entity($guid) can return objects not viewable by the current user, as long as the entity is found in memcache.
If it is not found, usual access restrictions work, because they are checked inside get_entity_as_row. This is with Elgg 1.7.7.
Change History (11)
comment:1 Changed 2 years ago by mrclay
- Cc steve@… added
comment:2 Changed 2 years ago by ewinslow
comment:3 Changed 2 years ago by mrclay
@evan, yep!
The remaining problem is that, when an entity's access changes, I see no way to invalidate the per-user visibility caches.
Perhaps a better design would store the access info more like the DB:
KeyValueStore.set("e123-acl") = 234 // or "public"/"private"/"loggedIn"
...as well as caching the ACL member lists:
KeyValueStore.set("acl234-guids") = [35,235,643]
Now you still have a straightforward way to see if user 643 can see entity 12, and better, when either entities or ACLs change, we can immediately reflect this in the key/value store without managing tons of keys or waiting for values to expire.
comment:4 Changed 2 years ago by cash
I prefer the later solution (storing access information in memcache).
comment:5 Changed 23 months ago by ewinslow
- Milestone changed from Needs Review to Elgg 1.9
comment:6 Changed 19 months ago by janlb
- Cc iamjanek@… added
comment:7 Changed 17 months ago by ebogdanov
- Severity changed from minor to major
We are using Elgg, and have the same issues,
If it is possible, I'll vote to fix that issue in upcoming Elgg release. It is almost critical, since memcache is unusable with that defect.
comment:8 Changed 8 months ago by coldtrick
- Severity changed from major to critical
comment:9 Changed 7 months ago by Steve Clay
- Resolution set to fixed
- Status changed from new to closed
Fixes #3018: Checks DB for access before using memcache-stored entity (suggested by Jerôme Bakker)
Changeset: 5c069bbca76fb8519548b2c8df2b9b6f3b3885b0
comment:10 Changed 7 months ago by Evan Winslow
Merge pull request #399 from mrclay/3018-memcache-access
Fixes #3018: Checks DB for access before using memcache-stored entity
Changeset: 84bf48937a7b294649701c1d6f4553dc0aeb4cd7
comment:11 Changed 5 months ago by cash
- Description modified (diff)
- Milestone changed from Near Term Future Release to Elgg 1.8.9

For persistent key-value stores like Memcache, the entity and some information about its access should be stored separately. E.g.:
Add a function:
/** * Can a user access an entity? * @return bool */ function elgg_user_can_access_entity($user_guid, $entity_guid) { // quick as possible DB check (don't hydrate the entity) }Each time an entity is stored in Memcached, this key/value must be stored separately:
"u{$current_user_guid}-sees-e{$entity_guid}" = true
When get_entity() finds an entity in Memcached, it must also check this "sees" key for the current user. If missing, it must call elgg_user_can_access_entity(), populating the "sees" key if it returns true. I don't suggest saving false because it's probably not a common case.