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

BT1-T142 : Check interaction between XSS and encryption #2149

Closed
wants to merge 12 commits into from

Conversation

Shnoulle
Copy link
Collaborator

@Shnoulle Shnoulle commented Nov 22, 2021

Dev: encryptSave validate by default
Dev: allow attribute filtering when encryotSave (see save function)

To be checked

  • application/models/SurveyDynamic.php:123: $record->encryptSave(); // In insertRecords : no 3.X check false retuened.
  • application/models/Participant.php:654: $result = $oParticipant->encryptSave(true);
  • application/models/Participant.php:1746: if (!$oToken->encryptSave(true)) {
  • application/models/Participant.php:2051: $oParticipant->encryptSave();
  • application/models/Participant.php:2055: $oTokenDynamic->encryptSave();
  • application/helpers/frontend_helper.php:419: $token->encryptSave();
  • application/helpers/remotecontrol/remotecontrol_handle.php:1893: if ($token->encryptSave(true)) {
  • application/helpers/remotecontrol/remotecontrol_handle.php:2072: if ($oToken->encryptSave(true)) {
  • application/helpers/remotecontrol/remotecontrol_handle.php:2888: $survey_dynamic->encryptSave();
  • application/helpers/remotecontrol/remotecontrol_handle.php:2992: $bResult = $aResponses[0]->encryptSave(true);
  • application/helpers/admin/import_helper.php:2204: if (!$token->encryptSave(true)) {
  • application/helpers/admin/import_helper.php:2533: if ($oSurvey->encryptSave()) {
  • application/helpers/expressions/em_manager_helper.php:5183: if (!$oResponse->encryptSave()) {
  • application/controllers/RegisterController.php:355: $oToken->encryptSave(true);
  • application/controllers/admin/participantsaction.php:718: $participant->encryptSave(true);
  • application/controllers/admin/dataentry.php:1491: if (!$oReponse->encryptSave()) {
  • application/controllers/admin/dataentry.php:1686: $new_response->encryptSave();
  • application/controllers/admin/dataentry.php:1752: $aToken->encryptSave(true);
  • application/controllers/admin/tokens.php:462: $bUpdateSuccess = $token->encryptSave(true);
  • application/controllers/admin/tokens.php:595: $inresult = $token->encryptSave(true);
  • application/controllers/admin/tokens.php:742: $result = $token->encryptSave(true);
  • application/controllers/admin/tokens.php:904: $token->encryptSave(true);
  • application/controllers/admin/tokens.php:1428: if (!$oToken->encryptSave(true)) {
  • application/controllers/admin/tokens.php:2154: if (!$oToken->encryptSave()) {
  • tests/unit/models/EncryptAttributesTest.php:38: $token->encryptSave(false);
  • tests/unit/models/EncryptAttributesTest.php:69: $token->encryptSave(true);
  • tests/unit/models/EncryptAttributesTest.php:108: $response->encryptSave(false);
  • tests/unit/models/EncryptAttributesTest.php:145: $response->encryptSave(true);

Dev: allow attribute filtering when encryotSave (see save function)
Dev: 1st part, test waiting
@Shnoulle Shnoulle marked this pull request as draft November 22, 2021 14:22
@Shnoulle Shnoulle marked this pull request as ready for review November 22, 2021 15:20
@Shnoulle Shnoulle marked this pull request as draft November 22, 2021 15:24
@Shnoulle Shnoulle marked this pull request as ready for review November 22, 2021 16:23
@Shnoulle
Copy link
Collaborator Author

OK, right : removed unused params from child function …

Copy link
Collaborator

@gabrieljenik gabrieljenik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structure of code seems ok

Copy link
Collaborator

@gabrieljenik gabrieljenik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is a problem in the frontend helper.
Initially, it decrypts all attributes.

Then encrypt, but only some.
Then the others are decrypted.

It does not break, because it is not saved.
But then it tries to decrypt everything back, and since they are already decrypted, an error occurs.

Will keep on reviewing later

@Shnoulle
Copy link
Collaborator Author

Then encrypt, but only some. Then the others are decrypted.

It does not break, because it is not saved. But then it tries to decrypt everything back, and since they are already decrypted, an error occurs.

related here : https://github.com/LimeSurvey/LimeSurvey/pull/2149/files#diff-4b5f6522204521a4e24e45dd60c31295cdc7298b0174dd96cf6c1e7d0334f4ffR420 ?

See 3.X :

$token->save(true, ['completed', 'usesleft']);

or here :
https://github.com/LimeSurvey/LimeSurvey/pull/2149/files#diff-fa8d35264aa59c85d37ca2d1756472996499f06fb346865594378102f5f7abc0R5184

In 3.X : we use updateByPk but here we need encrypt and save only needed values

Response::model($this->sid)->updateByPk($oResponse->id,$aResponseAttributes);

It's needed : we need to save only this values, encryot must happen only when save in my opinion :).

It's not an urgent fix here ;) January seems OK.

@gabrieljenik
Copy link
Collaborator

Hi Denis,

Generally speaking I am not too much in love in how encryption/decryption works for the token model.
Not a fan of havin to encrypt and decrypt everything, just for getting a single attribute.
Also, not sure if decrypting everything and keeping in status "decrypted" is the best.
I like more the ide of having getters that decrypt the info as needed and having the info stored all time encrypted inside the model.

Still, this is not the issue we are discussing.

On the curent code, if you follow these steps, you will get a 500

  • Create a new survey that uses tokens.
  • Set couple of attributes as encrypted.
  • Submit a response
  • A 500 error appears.

That happens as:

  • Frontendehelper:418 token is decrypted (all attributes)
  • Encryptsave encrypts some attributes (actually I think none, as "completed" and "usesleft" are sent as params)
  • Frontendehelper:423 token is decrypted (again, although no attributed is encrypted)

I would just remove Frontendehelper:418 and see if things workout like that.
image
image

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Dec 23, 2021

Strange : i think i do a test with token …

I can get a look in January : but i really think we must not encrypt what we don't save … Here :

public function encryptAttributeValues($attributes = null, $bEncryptedOnly = false, $bReplaceValues = true)

But you're right :

try to decrypt not encrypted value …

Different way to fix :

  1. Encrypt all attributes when save …
  2. Return decrypted Model after encryptSave …
  3. Add a filter on decrypt function
  4. Keep track of state of each attribute encrypted

I don't like 1 because if we don't need something we don't need to do it. I think 2 can broke at some other place For 3 : code need to track itself each attributes : seems not the best solution .

4 seems the best (in my opinion) ?

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Dec 23, 2021

PS :

Not a fan of havin to encrypt and decrypt everything, just for getting a single attribute.

Me too: don't like it :).

I like more the ide of having getters that decrypt the info as needed and having the info stored all time encrypted inside the model.

But you need to have it decrypted to use it, non ? Have 2 object : one for crypted and one decrypted ?
The have 2 Token object + 2 Response Object … arg …

@gabrieljenik
Copy link
Collaborator

gabrieljenik commented Dec 24, 2021

But you need to have it decrypted to use it, non ? Have 2 object : one for crypted and one decrypted ?
The have 2 Token object + 2 Response Object … arg …

Not actually. The attribute is always held encrypted on the model. A getter for attribute would check if it needs decryption. If so, does it, but don't store it, just return it for the script to use it as needed.

As it the data is always encrypted in the model and there is no diff in how the data is picked up or saved to the DB.

@Shnoulle
Copy link
Collaborator Author

Not actually. The attribute is always held encrypted on the model. A getter for attribute would check if it needs decryption. If so, does it, but don't store it, just return it for the script to use it as needed.

But this need to review all usage of token value and response value ?

@gabrieljenik
Copy link
Collaborator

But this need to review all usage of token value and response value ?

As with every other approach I guess.
We need to look for the current decrypt() calls to track the places where needed.

@Shnoulle
Copy link
Collaborator Author

Not actually. The attribute is always held encrypted on the model. A getter for attribute would check if it needs decryption. If so, does it, but don't store it, just return it for the script to use it as needed.

This make a lot more work …

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Dec 24, 2021

Must check the need … i can easily fix double decrypt, but rewriting all done is out of project i think.

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Jan 5, 2022

@gabrieljenik i fix the issue. Currently : when try to save a single attribute : encryot all attributes (like before).

Here : we can update $token->encryptSave(true, ['completed', 'usesleft']); by $token->save(true, ['completed', 'usesleft']); but in my opinion : for token and response : encryptSave function must not exist : save function must encrypt if needed.

Else : i give my opinion previously. In my opinion : all model->attribute must be decrypted transparently (and save as crypted transparently too).

@gabrieljenik
Copy link
Collaborator

gabrieljenik commented Jan 6, 2022

You're opinion : model->attribute must stay always crypted, must create or update getter and setter function for decrypt/uncrtyot

Yes, that was plan A.
Plan B is to decrypt on load, encrypt on save.
From a controller, not much difference from a regular model.

My (new) opinion : model->attribute must be always uncrypted, no need specific function or call. This can be done directly in
getAttributes($names=null)

Why there? What if someone tries to pick a specific encrypted attribute driectly. Like $model->attribute_encrtyped ?

but in my opinion : for token and response : encryptSave function must not exist : save function must encrypt if needed.

Agree. And load should unencrypt.

Else : i give my opinion previously. In my opinion : all model->attribute must be decrypted transparently (and save as crypted transparently too).

Agree. Question is what is the best way to accomplish that.

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Jan 6, 2022

Why there? What if someone tries to pick a specific encrypted attribute driectly. Like $model->attribute_encrtyped ?

I don't see any reason here ? But you're right …

The question now is 1. Make decision about all of this crypt system , 2. time of dev for project.

Both are done encryptSave validate by default + allow attribute filtering when encryptSave (see save function)

@gabrieljenik
Copy link
Collaborator

The question now is 1. Make decision about all of this crypt system , 2. time of dev for project.

Yes, this is more decision for @olleharstedt

@olleharstedt
Copy link
Collaborator

OK, I might have to spend some time reading this. ^^

@c-schmitz
Copy link
Contributor

I think this is a good effort. @ptelu should take a look at this next sprint so this can be finished.

@c-schmitz
Copy link
Contributor

@Shnoulle Can you fix the conflicts and then I will make sure it is reviewed?

@Shnoulle
Copy link
Collaborator Author

No conflicts on local merge …
Someone can test Participant again ?

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Jun 8, 2022

No conflicts on local merge … Someone can test Participant again ?

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Sep 16, 2022

@olleharstedt Need to fix conflict or work for nothing ?

@olleharstedt
Copy link
Collaborator

@olleharstedt Need to fix conflict or work for nothing ?

Idk man. We have a problem of ownership internally, when it comes to pull requests... :/

@Shnoulle
Copy link
Collaborator Author

Idk man. We have a problem of ownership internally, when it comes to pull requests... :/

See that …

@olleharstedt
Copy link
Collaborator

olleharstedt commented Sep 16, 2022

Problem is that Ahmed is still not replaced. We have a meeting about it later today. Hopefully we can get something moving.

@Shnoulle Shnoulle added the Decision needed Use when a discussion does not lead to consensus, to get a decision from Carsten/Olle/other label Oct 1, 2022
@Shnoulle
Copy link
Collaborator Author

@olleharstedt after more than one year … maybe we can close this PR ?

@olleharstedt
Copy link
Collaborator

olleharstedt commented Feb 9, 2023

@olleharstedt after more than one year … maybe we can close this PR ?

But there are still security issues solved by this PR or?

Also only one conflict so far.

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Feb 9, 2023

@olleharstedt after more than one year … maybe we can close this PR ?

But there are still security issues solved by this PR or?

I don't know … you don't explain the final reason. You ask me to encryptSave validate by default.

I think there are potential issue when adding feature or create plugin or currently exist but hidden

Also only one conflict so far.

Yes, but if I fix conflict toay , i don't want to fix it again in 4 month … I already have the impression to have developed for nothing on this pull request ...

@olleharstedt
Copy link
Collaborator

olleharstedt commented Feb 9, 2023

Yes, but if I fix conflict toay , i don't want to fix it again in 4 month … I already have the impression to have developed for nothing on this pull request ...

Yes, don't do anything now.

@Shnoulle
Copy link
Collaborator Author

Shnoulle commented Nov 3, 2023

Follow up on #3596

@Shnoulle Shnoulle closed this Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Decision needed Use when a discussion does not lead to consensus, to get a decision from Carsten/Olle/other Needs code review Needs testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants