Problem/Motivation

Currently, only textfield and textarea elements can be encrypted. But there are more elements that should be encrypted as well:

List of ALL elements provided by Webform:

Checkbox
Hidden
Password
Textarea
Text field
Autocomplete
CAPTCHA
CodeMirror
Color
Email
Email confirm
Email multiple
Number
Password confirm
Range
Rating
Search
Signature
Telephone
Text format
Toggle
URL
Value
Address
Contact
Location
Name
Buttons
Buttons other
Checkboxes
Checkboxes other
Likert
Radios
Radios other
Select
Select other
Table select
Tableselect sort
Table sort
Toggles
Container
Details
Fieldset
Flexbox layout
Item
Label
Date
Date/time
Date list
Time
Entity autocomplete
Entity checkboxes
Entity radios
Entity select
HTML markup
Message
Processed text
Table
Generic element

Proposed resolution

I think a good approach for this is allow the encryption for all elements by default, except for the elements listed in an "Exclusion List".

Since the webform elements are extensible, we can't have a hardcoded exclusion list, like on D7 version.

But we can have a default exclusion list containing some elements, like the types details, HTML markup, Table, etc, and then after or before this list be fetched, we trigger an event to allow other modules to change or add other elements.

Update:

The element types whitelist/blacklist is not necessary, since the webform module interface WebformElementInterface has the method isInput() to check whether the element is for input or not, please check the comment #6

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jribeiro created an issue. See original summary.

jribeiro’s picture

Assigned: Unassigned » jribeiro

Working on this.

jribeiro’s picture

New patch.

This patch allows the module to encrypt/decrypt all default webform elements, except the listed below, that doesn't make sense to encrypt.

      'captcha',
      'container',
      'details',
      'fieldset',
      'item',
      'label',
      'machine_name',
      'table',
      'webform_element',
      'webform_flexbox',
      'webform_wizard_page'

Major changes:

  • Implemented a new Event "webform_encrypt.elements_encrypt_exclusion_info" to allow other modules add new items to the exclusion list.
  • Removed "webform_encrypt.theme.inc" with the preprocess functions.
  • Created a custom Storage class extending the "WebformSubmssionStorage" to be able to decrypt the submissions data during the entity load.
  • Added support to elements that have multiple values.

Fixed https://www.drupal.org/node/2855766

jribeiro’s picture

Assigned: jribeiro » Unassigned
Status: Active » Needs review
jribeiro’s picture

jribeiro’s picture

I found a way to distinguish whether the Webform elements is for input data or not, by the method isInput() provided by the interface WebformElementInterface.

The method isInput() returns false for elements like container, details, captcha, in other words, elements that are not encrypted and stored on webform_submission_data table.

In this case the Event to whitelist/blacklist elements to be encrypted is not necessary since the module can verify it automatically now.

I've generated a new patch for this update.

jribeiro’s picture

Issue summary: View changes
jribeiro’s picture

Issue summary: View changes
badjava’s picture

Status: Needs review » Reviewed & tested by the community

I've tested #6 extensively and it works well. We are using it on several sites.

l0ke’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
15.41 KB
986 bytes

Currently encrypted data provided in doPostSave() method. This causes incorrect behavior like: encrypted data sent in webform submission emails etc.

Data should be decrypted for further PostSave processing, as handlers and emails. Solution is to override doPostSave() method in WebformEncryptSubmissionStorage and decrypt data before calling parent method.

jribeiro’s picture

Status: Needs review » Reviewed & tested by the community

Hi @l0ke, good catch with the email submissions, you are right, we need the doPostSave.

I tested your patch, looks good to me.

optimusprime619’s picture

@jribeiro & @l0ke thanks for this patch!

Not sure if this is worth mentioning but just reporting anyways.

I applied the patch 10, added an email field with encryption (no default value) to an existing webform (that I had made a prior submission).
Loading the form again results in the following undefined index notice messages

Notice: Undefined index: encrypted_mail in Drupal\webform_encrypt\WebformEncryptSubmissionStorage->getDecryptedData() (line 64 of modules/contrib/webform_encrypt/src/WebformEncryptSubmissionStorage.php).
Drupal\webform_encrypt\WebformEncryptSubmissionStorage->getDecryptedData(Object) (Line: 97)
Drupal\webform_encrypt\WebformEncryptSubmissionStorage->loadData(Array) (Line: 114)
Drupal\webform\WebformSubmissionStorage->loadMultiple(Array) (Line: 212)
Drupal\Core\Entity\EntityStorageBase->load('5') (Line: 283)
Drupal\webform\WebformSubmissionStorage->getTerminusSubmission(Object, NULL, Object, 'DESC') (Line: 239)
Drupal\webform\WebformSubmissionStorage->getLastSubmission(Object, NULL, Object) (Line: 568)
Drupal\webform\WebformSubmissionForm->displayMessages(Array, Object) (Line: 233)

Notice: Undefined index: encrypted_mail in Drupal\webform_encrypt\WebformEncryptSubmissionStorage->getDecryptedData() (line 73 of modules/contrib/webform_encrypt/src/WebformEncryptSubmissionStorage.php).
Drupal\webform_encrypt\WebformEncryptSubmissionStorage->getDecryptedData(Object) (Line: 97)
Drupal\webform_encrypt\WebformEncryptSubmissionStorage->loadData(Array) (Line: 114)
Drupal\webform\WebformSubmissionStorage->loadMultiple(Array) (Line: 212)
Drupal\Core\Entity\EntityStorageBase->load('5') (Line: 283)
Drupal\webform\WebformSubmissionStorage->getTerminusSubmission(Object, NULL, Object, 'DESC') (Line: 239)
Drupal\webform\WebformSubmissionStorage->getLastSubmission(Object, NULL, Object) (Line: 568)
Drupal\webform\WebformSubmissionForm->displayMessages(Array, Object) (Line: 233)
Drupal\webform\WebformSubmissionForm->buildForm(Array, Object)

badjava’s picture

@optimusprime619 Did you try following these same steps without the patch? This could be a pre-existing issue and not related specifically with the patch in which case a new issue should be created.

optimusprime619’s picture

@badjava not sure if I can do this without the patch since the ability to encrypt non textfield & textarea fields was available only through the patch along with the WebformEncryptSubmissionStorage.php. However, I haven't been able to reproduce the error message since that one occasion. In case if I am able to do so I will revert with details on the same as a new issue.

l0ke’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
15.69 KB
2.92 KB

I have an another finding.
Solution I've proposed in #10 to decrypt data at the beginning of doPostSave is not good enough.

Thing is when form is submitted by user who doesn't have a permission view encrypted values email have placeholder [Value Encrypted] instead of actual value.

Added parameter that controls permission check in decrypt method and run getDecryptedData with this parameter set to FALSE, so post save actions will always have an actual decrypted values.

jribeiro’s picture

@l0ke thanks for pointing that issue. I have tested #15, the patch looks good.

@optimusprime619 I could reproduce the issue #12 as well.

I generated a new patch containing the changes on #15 and the fix for #12.

badjava’s picture

Status: Needs review » Reviewed & tested by the community

Tested and running #16 on several sites - RTBC.

Christopher Riley’s picture

I also agree that this is RTBC as it makes the module actually useful.

jribeiro’s picture

I've just included an improvement to bypass the decrypt permission check if it is running through the command line interface, like Drush for example.

acbramley’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

With such large changes and given the sensitive nature of this module, we definitely need tests here.

acbramley’s picture

I've just manually tested and this seems like a really good improvement for the module. The only regression I can see currently is that for some reason the submission view pages are no longer being treated as admin pages (i.e they are themed with the site's frontend theme rather than admin theme). EDIT: Strangely enough once I debugged into it fixed itself, not sure what was happening there.

Other than that it fixes a lot of problems with encrypted values being shown to users that have access to decrypt.

I may have a look at writing some tests for this today.

acbramley’s picture

acbramley’s picture

Here's some pretty low level tests for checking that the correct values are displayed to the end user.

acbramley’s picture

FileSize
26.92 KB
4.82 KB

Add a test for the admin form changes too.

fenstrat’s picture

Status: Needs review » Reviewed & tested by the community

The tests added in #23 and #24 looks to cover things nicely. Given the re-architecture has been RTBC'd before I'm marking as such again.

Tests don't seem to be running (these are the first the d8 branch has). I think the module maintainer @th_tushar needs to enable qa on the 'Automated testing' tab of the module?

acbramley’s picture

Status: Reviewed & tested by the community » Needs work

Back to needs work, we've found a bug where a user with permission to view webform submission, but without the permission to see unencrypted values is able to view the unencrypted value via the submission route.

EDIT: To clarify, I believe this is a caching issue of some sort. Working on steps to reproduce now.
EDIT2: Even stranger, the bug only occurs with the destination param in the url (i.e when clicking the view button from the results page)

acbramley’s picture

I've tracked this down to the $_SERVER['argc'] variable being set on our environments. For some reason this is set to 1 when viewing a submission via the UI but only when the destination query parameter is set.

EDIT: This is caused by the ini setting register_argc_argv = On

acbramley’s picture

Status: Needs work » Needs review
FileSize
26.83 KB
586 bytes

Updated patch removing the check for argc.

acbramley’s picture

FileSize
1.22 KB
26.47 KB

After chatting about this more, I think we should have the same behaviour on CLI and UI. If you want to load submission values via drush you can use the -u parameter.

fenstrat’s picture

Status: Needs review » Reviewed & tested by the community

Had some more discussion on this. I agree that #29 is the right approach.

#29 changes the cli/drush behaviour, normally drush does not actively check any permissions. So the changes is actually a break from standard drush practice. However given the sensitive nature of the encrypted data then it seems like a sensible change. As @acbramley noted this could be overcome by running drush --user=1 ...

Tests still look like they need to be turned on for the d8 branch.

jrglasgow’s picture

this is working for me as well

jribeiro’s picture

The latest changes makes sense for me as well. I guess we are ready to go with it.

Waiting by the maintainer.

@th_tushar this issue is opened and RTBCed for a while, any chance to get it committed soon? This module needs an alpha release, that will help everyone to work on new improvements.

I would like to be a co-maintainer as well.

Thanks.

  • vijaycs85 committed 5d69ba1 on 8.x-1.x
    Issue #2855702 by jribeiro, acbramley, l0ke: Allow encryption for more...
vijaycs85’s picture

Status: Reviewed & tested by the community » Fixed

Thanks all. Commited to 8.x-1.x

th_tushar’s picture

Added jribeiro as a co-maintainer.

th_tushar’s picture

jribeiro’s picture

Thanks guys.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.