Page MenuHomeIn-Portal Phabricator

INP-1725 - Introduce secure Session Key generation/storage
ClosedPublic

Authored by alex on Aug 2 2024, 5:46 AM.

Details

Test Plan
NOTE: Semaphores & db load balancer aren't covered by the tests.
IMPORTANT: All testing is made on In-Portal 5.2.x unless noted otherwise.

Part 0 - Prepare In-Portal 5.2.2-B2

  1. in the phpMyAdmin:
    1. prepare an empty database (create empty OR clear existing) to be used during the install
  2. in the Terminal (SSH connection to Web Server)
    1. go to the DocumentRoot folder of the Web Server
    2. run the svn co svn://user@in-portal.org/in-portal/releases/5.2.2-B2 in-portal.522b2 command (replace user with your In-Portal SVN Server username) to perform an SVN Checkout
    3. switch to the just created in-portal.522b2 folder
    4. run the php tools/configure_profile.php in-portal.full command to update svn:externals property
    5. run the svn update command to checkout missing modules/themes
    6. (in IDE) change value of the "name" key in the "/composer.json" file from "In-Portal" to "intechnic/in-portal"
    7. run the composer update command to create a vendor folder
    8. run the tools/fix_perms.sh command to fix permissions of the system folder
    9. run the cp tools/debug_sample.php system/debug.php to create a debug file
  3. in IDE (for In-Portal 5.2.2-B2 installation):
    1. open /system/debug.php file for editing
    2. update $dbg_options['DBG_IP'] key as needed (add your IP address for Debug Mode to be enabled)
    3. uncomment the DBG_CURL constant definition
    4. save changes
    5. copy /index.php file into /curl_test.php file
    6. open /curl_test.php file for editing
    7. replace $application->Run(); line with $application->recallObject('CurlHelper')->Send('https://www.google.com'); code
    8. save changes
  4. in the Web Browser:
    1. go the URL, that matches SVN checkout folder
    2. click on the link that recommends to perform installation
    3. perform In-Portal installation:
      • with all the modules
      • with advanced theme set as primary
      • with System Log enabled
    4. open the curl_test.php file
    5. (in the phpMyAdmin) confirm, that the CurlLog table isn't empty (record is present about cURL request)
    6. login to the Admin Console
    7. go to the Logs & ReportsSystem Log section
    8. confirm, that grid isn't empty (the record is present about "InstallFinished" system setting)
    9. go to the E-commerceSales Report section
    10. run any report
    11. (in phpMyAdmin) confirm, that 522b2_ses_NNN_SaleReport table was created (522b2_ is table prefix; NNN is session key)
    12. go to the ConfigurationWebsiteAdvanced section
    13. enable the Track database changes to change log and save changes
    14. re-logout to the Admin Console
    15. go to the Logs & ReportsSession Log section
    16. confirm, that grid isn't empty (record about current session is present)
    17. open editing of any record, that will cause temp table to be created, but don't close the editing popup/modal window
    18. (in the phpMyAdmin) confirm, that temporary tables were created for unit, that is edited
    19. remember your SID from adm_sid cookie
  5. in the Web Browser
    1. go to the Front-End
    2. perform any search requery
  6. in phpMyAdmin
    1. confirm, that 522b2_ses_NNN_522b2_Search table was created (522b2_ is table prefix; NNN is session key)
    2. remember how temporary tables/sales report tables/search tables are named (SID in the table name)
    3. remember SID usage in the UserSessions, UserSessionData, UserSessionLogs, CurlLog, SystemLog tables
    4. backup the database in case if something wents wrong with an upcoming upgrade and it needs to be repeated

Part 1 - Testing Upgrade (for In-Portal 5.2.x installation)

  1. in IDE:
    1. apply patches from the D477 and D476
    2. backup /system/config.php and /system/debug.php files
    3. replace /system/config.php and /system/debug.php files with their counterparts from the In-Portal 5.2.2-B2 installation
    4. open /system/config.php file for editing
    5. change $_CONFIG['Misc']['WebsitePath'] to represent In-Portal 5.2.x installation path
    6. save changes
  2. in Web Browser
    1. open the /core/install.php URL
    2. (in phpMyAdmin) remember row count of the UserSessionLogs table
    3. proceed with the upgrade
    4. (in phpMyAdmin) confirm, that no new rows were created in the UserSessionLogs table during the upgrade
    5. login to the Admin Console
    6. change adm_sid and adm_sid_live cookie value into previously (before upgrade) recorded (see prev. test part)
    7. reload the page (frameset)
    8. confirm, that you're still logged in
  3. in phpMyAdmin:
    1. confirm, that temporary tables/sales report tables/search tables are property renamed (SID is replaced with Session ID)
    2. confirm, that SID usage in the UserSessions, UserSessionData, UserSessionLogs, CurlLog, SystemLog tables was replaced with it's hash

Part 2 - Temp tables

/admin/temp_test.php (fragment)
$live_table = TABLE_PREFIX . 'Categories';
$temp_table = $application->GetTempName($live_table);
$is_temp_table_true = $application->IsTempTable($temp_table);
$is_temp_table_false = $application->IsTempTable($live_table);
$live_table_rebuilt1 = $application->GetLiveName($temp_table);
$live_table_rebuilt2 = $application->GetLiveName($live_table);

echo 'LT: ' . $live_table . '<br/>' . PHP_EOL;
echo 'TT: ' . $temp_table . '<br/>' . PHP_EOL;
echo 'TTT: ' . ($is_temp_table_true ? 'OK' : 'FAILED') . '<br/>' . PHP_EOL;
echo 'TTF: ' . (!$is_temp_table_false ? 'OK' : 'FAILED') . '<br/>' . PHP_EOL;
echo 'LTR1: ' . ($live_table_rebuilt1 === $live_table ? 'OK' : 'FAILED') . '<br/>' . PHP_EOL;
echo 'LTR2: ' . ($live_table_rebuilt2 === $live_table ? 'OK' : 'FAILED') . '<br/>' . PHP_EOL;
  1. in Web Browser
    1. perform the clean install
    2. login to the Admin Console
    3. go to ConfigurationAdvanced section
    4. change value of the Editing Window Style system setting to the Popup Window
    5. save changes
    6. reload the whole frameset
  2. in IDE:
    1. copy/paste /admin/index.php file into /admin/temp_test.php file
    2. replace $application->Run(); line with the above shown code fragment
    3. save changes
  3. in Web Browser
    1. open /admin/temp_test.php file
    2. confirm, that:
      • first test shows valid LIVE table name
      • second test shows valid TEMP table name
      • other 4 tests show OK
    3. (in phpMyAdmin) confirm, that no temporary tables for given admin session are present
    4. press Add toolbar button to open 1st new record creation popup
    5. return back to the main window
    6. press Add toolbar button to open 2nd new record creation popup
    7. (in phpMyAdmin) confirm, that:
      • 2 sets of temporary tables for these actions were created
      • they have session_id instead of session_key in their names
    8. close one of the editing windows using an X icon in top right corner of the window
    9. wait 2 seconds
    10. (in phpMyAdmin) confirm, that 1 set of temporary tables for the closed window was removed

Part 3 - Debugger

NOTE: Debugger must be enabled before performing this test.
  1. in Web Browser:
    1. go to the Admin Console
    2. open any grid to trigger debug report file generation (but don't open debugger report)
  2. in IDE:
    1. open the /system/.restricted folder
    2. confirm, that some debugger report files are in the new format (debug_@SID_HASH@.txt) instead of (debug_@SID@.txt)
    3. create an empty /system/.restricted/debug_@fake_sid@.txt file
    4. (in CLI) run the php tools/run_event.php adm:OnOptimizePerformance b674006f3edb1d9cd4d838c150b0567d command
    5. confirm, that:
      • /system/.restricted/debug_@fake_sid@.txt file was removed
      • /system/.restricted/debug_@*@.txt files belonging to non-existing/expired sessions were removed

Part 4 - cURL

  1. in IDE:
    1. open /system/debug.php file for editing
    2. uncomment the DBG_CURL constant definition
    3. save changes
    4. copy /index.php file into /curl_test.php file
    5. open /curl_test.php file for editing
    6. replace $application->Run(); line with $application->recallObject('CurlHelper')->Send('https://www.google.com'); code
    7. save changes
  2. in Web Browser
    1. open the /curl_test.php file
    2. (in the phpMyAdmin) confirm, that:
      • the CurlLog table isn't empty
      • the CurlLog.SessionKey column contains SID hash (as see in the UserSessions.SessionKey column)

Part 5 - Sub-item grid filters in temp table

  1. in the Web Browser
    1. go to Admin Console
    2. go to Website & ContentPolls section
    3. press the Add toolbar button
    4. fill-in required fields on the General tab (in popup, that opens)
    5. go to the Answers tab
    6. add one answer
    7. try searching in the Answer column (no column title) for something, that is present in the answer
    8. confirm, that that something is found
    9. try searching in the Answer column (no column title) for something, that isn't present in the answer
    10. confirm, that that nothing is found

Part 6 - System Log

  1. in the Web Browser
    1. go to Admin Console
    2. go to Website & ContentPolls section
    3. press the Add toolbar button
    4. press Save toolbar button without filling-in the required fields
    5. confirm, that you see a validation error
    6. press the Cancel toolbar button
    7. go to Logs & ReportsSystem Log section
    8. open system log record, that was created after the validation error
    9. confirm, that Session Key shows SID hash (as see in the UserSessions.SessionKey column)

Part 7 - Sales Report

  1. in the Web Browser
    1. go to E-commerceSales Report section
    2. run the report with any valid values
    3. confirm, that you're seeing a grid
    4. (in phpMyAdmin) confirm, that 522b2_ses_1_SaleReport table was created (522b2_ is table prefix; 1 is session id)

Part 8 - Front-End search

  1. in the Web Browser
    1. go to Front-End
    2. try searching for anything
    3. (in phpMyAdmin) confirm, that 522b2_ses_1_522b2_Search table was created (522b2_ is table prefix; 1 is session id)

Part 9 - Session Logs

  1. in the Web Browser
    1. go to Admin Console
    2. go to the ConfigurationWebsiteAdvanced section
    3. enable the Track database changes to change log and save changes
    4. re-logout to the Admin Console
    5. go to the Logs & ReportsSession Log section
    6. confirm, that grid isn't empty
    7. confirm, that Session Key column is visible
    8. (phpMyAdmin) confirm, that record created in the UserSessionLogs table has SessionId and SessionKey column values, that match with an existing session from the UserSessions table

Part 10 - Session itself

/admin/session_test.php (fragment)
echo 'T1: ' . ($application->Session->GetField('NonExistingField') === false ? 'OK' : 'ERROR') . '<br/>' . PHP_EOL;
echo 'T2: ' . ($application->Session->GetField('TimeZone') === '' ? 'OK' : 'ERROR') . '<br/>' . PHP_EOL;

$application->Session->SetField('TimeZone', 'Europe/London');
echo 'T3: ' . ($application->Session->GetField('TimeZone') === 'Europe/London' ? 'OK' : 'ERROR') . '<br/>' . PHP_EOL;

$application->Session->SetField('TimeZone', null);
echo 'T4: ' . ($application->Session->GetField('TimeZone') === null ? 'OK' : 'ERROR') . '<br/>' . PHP_EOL;
  1. in the Web Browser
    1. go to Admin Console
    2. (in IDE) delete all the debugger report files from the /system/.restricted folder
    3. click on any page
    4. (in IDE) confirm, that debugger report file was created
    5. (in phpMyAdmin) confirm, that records in UserSessions and UserSessionData tables for current session are present
    6. perform logout
    7. (in IDE) confirm, that debugger report for the just logged out session was deleted
    8. (in phpMyAdmin) confirm, that records in UserSessions and UserSessionData tables for just logged out session were deleted
    9. perform logout
    10. (in IDE) replace $application->Run(); line in /admin/index.php file with $application->GetSID(Session::PURPOSE_REFERENCE); and save changes
    11. reload the page
    12. confirm, that an exception is thrown (in Debugger Report) about non-existing session and it shows it's session key
    13. (in IDE) rollback changes to the /admin/index.php file and save changes
    14. login to the Admin Console
  2. in IDE:
    1. copy/paste /admin/index.php file into /admin/session_test.php file
    2. replace $application->Run(); line with the above shown code fragment
    3. save changes
  3. in Web Browser
    1. open /admin/session_test.php file
    2. confirm, that: all 4 tests show OK

Part 11 - parallel editing

  1. in the Web Browser
    1. go to Admin Console
    2. go to Website & ContentStructure & DataDirectory section
    3. click on the Links tab
    4. create one record in that grid
    5. open that record for editing
    6. return back to main window
    7. open that record for editing again
    8. confirm, that you're seeing an alert indicating, that this record is already being edited

Part 12 - session logout on user disapproval

  1. in the Web Browser
    1. go to Admin Console (tab 1)
    2. go to User ManagementUsers section
    3. create a user
    4. go to Front-End (tab 2)
    5. login using that user
    6. go to Admin Console (tab 1)
    7. deactivate just created user using Disable button from the grid
    8. go to Front-End (tab 2)
    9. reload the page
    10. confirm, that you're no longer logged-in on the Front-End

Diff Detail

Repository
rINP In-Portal
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

alex created this revision.Aug 2 2024, 5:46 AM
alex requested review of this revision.Aug 2 2024, 5:46 AM
alex updated this revision to Diff 1230.Aug 2 2024, 5:50 AM

Sent changes from the wrong changelist

alex updated this revision to Diff 1231.Aug 2 2024, 6:06 AM

CS fixes

alex edited the test plan for this revision. (Show Details)Aug 2 2024, 6:07 AM
alex retitled this revision from Default to INP-1725 - Introduce secure Session Key generation/storage.
alex added 1 JIRA issue(s): INP-1725.
erik requested changes to this revision.Aug 2 2024, 10:35 AM

Test failed on Part 1 - Testing Upgrade (for In-Portal 5.2.x installation), in Web Browser open the /core/install.php URL

InvalidArgumentException: The HMAC key is empty. in w:\SVN\5.2.x\core\kernel\security\SecurityEncrypter.php on line 96

Also bug detected on step Part 0 - Prepare In-Portal 5.2.2-B2 in the Web Browser open editing of any record, that will cause temp table to be created, but don't close the editing popup/modal window

Tried for opening category edit "Directory (TD)" category. No success with modal window - shown modal window loading "progress bar", and nothing happened.

Test become possible to continue only after changed system setting from "modal window" to "popup". Category edit popup opened without problems.

This revision now requires changes to proceed.Aug 2 2024, 10:35 AM
alex edited the test plan for this revision. (Show Details)Aug 2 2024, 11:17 AM
erik added a comment.Aug 5 2024, 7:31 AM

All tests passed, excepting "confirm, that `Session Key: ..." line shows different value, than before (proves, that active sessions in the old format were upgraded and remain active)"

Session Key becomes unchanged in both cases - when used root user, and when used two different admin users.

Also, after session ID cookie change system does not working properly - after logout happens infinite redirect.

alex updated this revision to Diff 1234.Aug 13 2024, 3:30 AM
  1. removed Session Key: ... line in Debugger Report, because session key is already visible in the SQL query made before it
  2. [bugfix] new sid uniqueness checking during generation was made using SID itself and not it's hash
alex added a comment.Aug 13 2024, 3:33 AM

@erik , you can safely accept without testing, because I've removed the code, that was causing the test to fail. Indeed code contained an error, but it's no longer needed.

alex edited the test plan for this revision. (Show Details)Aug 13 2024, 3:34 AM
erik accepted this revision.Aug 14 2024, 7:16 AM
This revision is now accepted and ready to land.Aug 14 2024, 7:16 AM
This revision was landed with ongoing or failed builds.Aug 16 2024, 3:27 AM
This revision was automatically updated to reflect the committed changes.