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

WAF: Improve cross-compatibility of IP list options #38395

Merged
merged 3 commits into from
Jul 19, 2024

Conversation

nateweller
Copy link
Contributor

@nateweller nateweller commented Jul 17, 2024

Proposed changes:

  • Update the WAF REST API endpoint to compute the legacy "jetpack_waf_ip_lists" value based on the new block and allow list option values, and similarly set the new block and allow list values directly when the legacy "jetpack_waf_ip_lists" parameter is included in a POST request.
  • Use Jetpack_Options::get_raw_option() in compatibility hooks, to use the unfiltered value from the database.
  • Use '1' or '' as option values to ensure related hooks fire (source).
  • Update/fix tests to correctly mock option values.

Other information:

  • Have you written new tests for your changes, if applicable?
  • Have you checked the E2E test CI results, and verified that your changes do not break them?
  • Have you tested your changes on WordPress.com, if applicable (if so, you'll see a generated comment below with a script to run)?

Jetpack product discussion

N/A

Does this pull request change what data or activity we track or use?

No

Testing instructions:

  • Set up a site with running one of the following environments:
    • Jetpack with branch applied, Protect from production
    • Jetpack from production, Protect with branch applied
    • Both Jetpack AND Protect with branch applied
    • Jetpack OR Protect with branch applied
  • Test toggling between the Jetpack and Protect WAF UI, and updating the new block and allow list toggles in Protect, and updating the legacy IP lists toggle in Jetpack.

@nateweller nateweller self-assigned this Jul 17, 2024
@nateweller nateweller requested a review from a team July 17, 2024 21:03
Copy link
Contributor

github-actions bot commented Jul 17, 2024

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WordPress.com Simple site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin, and enable the add/waf/ip-list-cross-compat branch.

  • To test on Simple, run the following command on your sandbox:

    bin/jetpack-downloader test jetpack add/waf/ip-list-cross-compat
    

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

Copy link
Contributor

github-actions bot commented Jul 17, 2024

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Team Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


The e2e test report can be found here. Please note that it can take a few minutes after the e2e tests checks are complete for the report to be available.


Once your PR is ready for review, check one last time that all required checks appearing at the bottom of this PR are passing or skipped.
Then, add the "[Status] Needs Team Review" label and ask someone from your team review the code. Once reviewed, it can then be merged.
If you need an extra review from someone familiar with the codebase, you can update the labels from "[Status] Needs Team Review" to "[Status] Needs Review", and in that case Jetpack Approvers will do a final review of your PR.

@nateweller nateweller added [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Status] Needs Team Review and removed [Status] In Progress [Tests] Includes Tests labels Jul 17, 2024
@nateweller nateweller force-pushed the add/waf/ip-list-cross-compat branch from 4f0663f to 612992c Compare July 17, 2024 22:02
@nateweller nateweller marked this pull request as ready for review July 18, 2024 20:07
@nateweller nateweller force-pushed the add/waf/ip-list-cross-compat branch from 6c1a218 to 6778532 Compare July 18, 2024 20:11
Copy link
Contributor

@dkmyta dkmyta left a comment

Choose a reason for hiding this comment

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

Code looks good, one non-blocking suggestion to maintain consistency.

Had some initial issues testing - installed the branch via the beta tester on a JN site that had pre-existing legacy options set (manual rules enabled or disabled). Regardless of the existing settings, after installing the branch the manual rules show as on and toggling from either Jetpack or Protect does not work. The request succeeds and the payload looks correct jetpack_waf_ip_list: false, but the response continues to include jetpack_waf_ip_list: true, the toggle flips momentarily but returns to the on position.

Works great on a fresh JT install, even after downgrading and/or using an outdated version of the other plugin. Odd thing is, if I install the new version, modify settings, downgrade, modify settings, then upgrade again, it works as expected. I was under the impression that doing this would present the same issues as starting from and old version and upgrading, but perhaps because in this particular case the new options are already set from the new version being installed initially, vs in the other case, they did not exist when upgrading?

UPDATE: Although still worth a deeper look, I was unable to reproduce the issue on another installation with a similar setup, so its potentially just a one-off - I've provided you login creds privately so you can take a look at the problematic site.

Another thing I did notice though was on the first time enabling the manual rules setting using the branch, after hitting the toggle it was disabled for a noticeably longer time then any subsequent toggles - perhaps irrelevant or might have always been the case but thought it worthy of a note.

@@ -179,7 +179,7 @@ public static function get_config() {
* @deprecated $next-version$
*/
// @phan-suppress-next-line PhanDeprecatedClassConstant -- Needed for backwards compatibility.
Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME => get_option( Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME ),
Waf_Rules_Manager::IP_LISTS_ENABLED_OPTION_NAME => get_option( Waf_Rules_Manager::IP_ALLOW_LIST_ENABLED_OPTION_NAME ) || get_option( Waf_Rules_Manager::IP_BLOCK_LIST_ENABLED_OPTION_NAME ),
Copy link
Contributor

Choose a reason for hiding this comment

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

To maintain consistency with other related operations, should we use Jetpack_Options::get_raw_option() here also?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting question! After double checking the logic, I don't think these should be changed.

I'm using get_option here so that it uses the default value hooks for the block and allow list. This ensures that if the deprecated option was set, and the new options are not, they will base their value on the old one and still return an accurate value 👍

In the compatibility class, I used get_raw_option to bypass those filters, in order to make those default value decisions based on the "true" value of the options in the database.

But at this point, in the runner class, we want those default values to be used 👍

@nateweller
Copy link
Contributor Author

Had some initial issues testing - installed the branch via the beta tester on a JN site that had pre-existing legacy options set (manual rules enabled or disabled). Regardless of the existing settings, after installing the branch the manual rules show as on and toggling from either Jetpack or Protect does not work. The request succeeds and the payload looks correct jetpack_waf_ip_list: false, but the response continues to include jetpack_waf_ip_list: true, the toggle flips momentarily but returns to the on position.

Some notes from debugging on this particular test site:

  • The deprecated jetpack_waf_ip_list option was set to "" (disabled).
  • The jetpack_waf_ip_allow_list_enabled and jetpack_waf_ip_block_list_enabled options were both set to 1 (enabled).
  • Since the REST API uses the new values to compute the value for jetpack_waf_ip_list, it was correctly returning true for the value.
  • Setting the value to false also correctly sent a request with a payload where jetpack_waf_ip_list as false.
  • The update endpoint correctly attempted to update the individual block and allow list settings to "" (disabled). The update_option call got all the way to the $wpdb->update call, where it failed and returned false. This is where the error is happening.
  • Strangely, turning automatic rules on from the Jetpack settings fixed the issue and it stopped being reproducible on the test site.

@nateweller nateweller closed this Jul 19, 2024
@nateweller nateweller reopened this Jul 19, 2024
@github-actions github-actions bot added [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! and removed [Status] In Progress labels Jul 19, 2024
… jetpack_waf_ip_allow_list_enabled and jetpack_waf_ip_block_list_enabled settings
@nateweller nateweller force-pushed the add/waf/ip-list-cross-compat branch from 6778532 to 5cb95bf Compare July 19, 2024 19:46
@nateweller
Copy link
Contributor Author

Works great on a fresh JT install, even after downgrading and/or using an outdated version of the other plugin. Odd thing is, if I install the new version, modify settings, downgrade, modify settings, then upgrade again, it works as expected. I was under the impression that doing this would present the same issues as starting from and old version and upgrading, but perhaps because in this particular case the new options are already set from the new version being installed initially, vs in the other case, they did not exist when upgrading?

If you upgrade, make changes, and then downgrade - it would go back to using the deprecated option value, which is never modified or used directly by the upgraded version.

Likewise, if you go back to the upgraded version, where you already had set values for the new options, it will always use those directly.

So I am not sure if it would always keep the changes you made in the middle of that process, as when the latest values are available when running the updated code, it will always use those. I'm not too worried about the case where the updated version is installed, used, and then downgraded though.

@nateweller nateweller requested a review from dkmyta July 19, 2024 20:07
@nateweller nateweller removed the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jul 19, 2024
@nateweller
Copy link
Contributor Author

Made some minor adjustments, this is good for re-review @dkmyta 🙇

Copy link
Contributor

@dkmyta dkmyta left a comment

Choose a reason for hiding this comment

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

I think we're solid here! I was not able to replicate the original issue - I think we can conclude that it was definitely an odd one-off that we do have handling for.

As we discussed, there is not much we can do about the edge case where one or the other plugin is using the legacy version and have a single IP list toggled in the upgraded version, but I agree that the following is a logical solution:

  • Disabling manual rules in the legacy UI disables both lists in the upgraded UI
  • Disabling both lists in the upgraded UI disables manual rules in the legacy UI
  • Enabling any one list in the upgraded UI enables manual rules and access to both lists in the legacy UI (and updates to a disabled list re-enable it in the upgraded UI)

@dkmyta dkmyta self-requested a review July 19, 2024 20:48
@nateweller nateweller merged commit aef6b3a into trunk Jul 19, 2024
71 of 73 checks passed
@nateweller nateweller deleted the add/waf/ip-list-cross-compat branch July 19, 2024 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] WAF [Tests] Includes Tests [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants