Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FormitRetriever without sessions but cache storage causes potential data leak or data loss #267

Open
wuuti opened this issue Jun 3, 2022 · 1 comment

Comments

@wuuti
Copy link

wuuti commented Jun 3, 2022

Bug report

Summary

If FormitRetriever is used with storeLocation "cache" (which is the default), and sessions are not used (anonymous_sessions/sessions_enabled) in the context, concurrent requests to form pages can:

  • show data other users have entered in the form (data leak), - often seen on confirmation pages
  • delete data which has been entered by other users (data loss), with eraseOnLoad being set

Step to reproduce

Its hard to directly reproduce, as this only happens if concurrent requests happening at almost the same time are done on the form pages. Thats also the reasons the error is not seen on small pages, because traffic and concurrent requests there are very unlikely.
But larger pages or pages with peak loads (maybe due to a newsletter or some other offline "promotion") will have these problems.

But the behaviour is obvious when looking at the code which creates the cache-key to store the form data:

  return $this->modx->context->get('key') . '/elements/formit/submission/' . md5(session_id());

In sessionless contexts, the value of session_id() is always the empty string! Which causes the md5 to be a static value (md5 of empty string is always "d41d8cd98f00b204e9800998ecf8427e") and therefore every form post will write to the same cache file!

Expected behavior

Without a session there is no out-of-the-box way to have any persistent identifier to connect formit steps with redirects together (essentially making multi-step forms and confirmation pages with form content in the "traditional" impossible).

Mitigation steps:

  • explicitly warn in the documentation that FormitRetriever cannot be used in sessionless contexts (regardless of the storagelocation!)
  • change the code, so that the getStoreKey method logs a warning/error if session_id is empty - so that modx admins currently having that setup at least are warned, that something may go wrong with their forms
  • in the longer term, formit should instead for sessionsless contexts:
    • create a unique hash per formit call
    • hash needs to be added as hidden form input field (on every form in multistep forms)
    • redirect should automatically add the hash value as an url/query parameter
    • formitretriever should use that param instead of session_id to retrieve previous data from cache
@wuuti
Copy link
Author

wuuti commented Jun 3, 2022

Seems the code was in there since 2010, which was ok in those days. But in when Modx 2.2.1 introduced sessionless contexts in 2012, it became wrong, but no one noticed...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant