Commit graph

687 commits

Author SHA1 Message Date
Thalia 47fb507e28 maintenance/SearchFilters: Allow searching by privacy level
Why:

* Filters should only be protected if they contain protected
  variables, or have done in the past.
* Before T377765, it was possible to protect any filter, and at
  least one filter was mistakenly protected.
* To check whether any other filters have been mistakenly
  protected, it is helpful to run a query on all databases for
  protected filters.

What:

* Add an option to maintenance/SearchFilters to allow searching
  by privacy level.

Bug: T380290
Change-Id: I40837de7c63fb8001734df80524a0bf79ff50135
2024-11-26 07:25:04 +00:00
jenkins-bot d81c3f4c3a Merge "Migrate 'ArticleDelete' hook to 'PageDelete' to fix error display" 2024-11-24 16:51:33 +00:00
Aaron Schulz f1f2f601ef Set "StatsdServer" in PurgeOldLogIPDataTest for maintenance script
Change-Id: I55ab7244aad1054763aabdf323cf11130cc99069
2024-11-21 11:20:19 -08:00
jenkins-bot 68433f9962 Merge "Add RemoveProtectedFlagFromFilter maintenance script" 2024-11-15 15:56:25 +00:00
Thalia 91456d79b2 Add RemoveProtectedFlagFromFilter maintenance script
Why:

* Protected variables were introduced to support temporary accounts
  so that temporary users could be filtered based on their IP address.
* Filters that use protected variables are protected in order to
  preserve privacy. This can't be undone.
* It is mistakenly possible to protect a filter that does not use
  protected variables (T378553). We need a mechanism to fix these
  mistakes.

What:

* Introduce a maintenance script that takes a filter ID and, if the
  filter is protected, sets it to unprotected while maintaining any
  other existing privacy levels.

Bug: T378551
Change-Id: I4dfe3970221397d5be5ea0697490d8c8e3726adf
2024-11-15 13:13:38 +00:00
Thalia 8de5b4e1aa Improve workflow for protecting filters with protected variables
Why:

* Protected variables were introduced to support temporary accounts
  so that temporary users could be filtered based on their IP address.
* Filters that use protected variables are protected in order to
  preserve privacy. This can't be undone.
* The current workflow for protecting filters is to have a 'protect'
  checkbox that can be checked for any filter, even one without
  protected variables, to the discretion of the editor. This has
  led to mistakes (see T37765).

What:

* Do not show the 'protect' checkbox on the form by default. Instead,
  show it when saving a filter with protected variables, after form
  submission. The user must check it to save the filter.
* Still show the checkbox in a disabled state with a warning message
  if a filter is already protected, so that the editor can easily see
  it is protected.

Bug: T377765
Change-Id: Ie5c94ac1399860ccdca4482508dd37ff07309764
2024-11-14 18:24:27 +00:00
Thalia 6a14ea54fb AbuseFilterViewEdit: Expose status object to form builder
Why:

* For improvements to the protected filters workflow (T377765),
  a checkbox needs to be displayed conditionally on the status
  of a previously submitted form.

What:

* Pass a status object into ::buildFilterEditor, and build the
  HTML for any warnings or errors in that function, instead of
  first building the HTML and passing it.
* This also allows more than one error and/or warning to be
  shown if present, though this may not happen in practice yet.

Change-Id: I37da49711e7fc192856f013cd931c05379f8e8c6
2024-11-14 18:23:25 +00:00
Thalia 2cb1ad0f58 SpecialAbuseFilterTest: Remove unused trait
Remove the use statement for MockAuthorityTrait, which is unused.
We can't use it because SpecialAbuseFilter checks permissions on
the user, not the authority.

Change-Id: I2baca5753dd9e21aa90b6856c5850d1100eda4d5
2024-11-13 18:57:18 +00:00
Dreamy Jazz 774f4f02ef Create protected variable access logs POSTSEND
Why:
* The ProtectedVarsAccessLogger::logViewProtectedVariableValue
  method creates a debounced log entry for accessing protected
  variable values.
* This log can be created when a user calls the 'abuselog' query
  API. This API query is made using a GET request.
* Because the ProtectedVarsAccessLogger creates the log
  when it is called, the TransactionProfiler raises a warning
  about writing to the primary DB on a GET request.
* We should address this warning by creating the log entry on
  POSTSEND, in a similar way to how the CheckUser extension
  creates CheckUser log entries.

What:
* Wrap the call to ProtectedVarsAccessLogger::log in
  ::logViewProtectedVariableValue with a DeferredUpdate callback
  that is run POSTSEND.
** As part of this, the expectations that the code only uses the
   replica DBs are silenced inside the DeferredUpdate as the
   PostSend-GET expectations do not usually allow for writes.
   The only other method would to be create the log via a job,
   but we want the log creation to occur quickly and reliably.

Bug: T379083
Change-Id: If14e65b27b0bdd4fd0b99319024ffa281bf44656
2024-11-11 14:33:47 +00:00
Andre Klapper 63de22357d Use explicit nullable type on parameter arguments (for PHP 8.4)
Implicitly marking parameter $... as nullable is deprecated in PHP
8.4. The explicit nullable type must be used instead.

Bug: T376276
Change-Id: I303342cf1a002d5f0afc77ce147ce9453ea5282e
2024-10-26 14:38:46 +02:00
jenkins-bot ad516227f4 Merge "Protected variable logs: fallback to accountname if user_name is not set" 2024-10-21 20:18:15 +00:00
Bartosz Dziewoński 6b0c6609d1 Migrate 'ArticleDelete' hook to 'PageDelete' to fix error display
Bug: T377384
Change-Id: Ia8df47ffc9a77dabd00c97731b2e335901897bf0
2024-10-21 21:35:27 +02:00
Kosta Harlan 05da3118aa
Protected variable logs: fallback to accountname if user_name is not set
Why:

- For account creations and account autocreations, the user_name
  property is deliberately unset, to avoid displaying the IP address of
  an unregistered user. Instead, `accountname` is set with the newly
  created account name
- For logging that someone has seen a protected variable value, we need
  to record the username that was seen

What:

- Use `accountname` as a fallback in case `user_name` is not set, when
  logging protected variable access
- Update tests to cover this case.

Bug: T376885
Change-Id: I688a3529fac0ad8455977a0cfdb950f0105f550d
2024-10-21 21:15:51 +02:00
Umherirrender 57ecef75c5 Use namespaced classes
Changes to the use statements done automatically via script
Addition of missing use statement done manually

Change-Id: If80031678a474157e4cc78a3d3621dab53aded67
2024-10-19 21:55:40 +02:00
jenkins-bot 743bb64924 Merge "Log specific views of protected variables" 2024-10-03 14:37:48 +00:00
STran b66daede0a Log specific views of protected variables
Like CheckUser, AbuseFilter should also log when specific protected
logs are viewed.

- Add support for debouncing logs to reduce log spam
- Log when AbuseFilterViewExamine with protected variables available
  is accessed
- Log when SpecialAbuseLog with protected variables available is
  accessed
- Log when QueryAbuseLog with protected variables available is accessed

Bug: T365743
Change-Id: If31a71ea5c7e2dd7c5d26ad37dc474787a7d5b1a
2024-10-02 00:53:34 -07:00
Dreamy Jazz 48b26792a9 SECURITY: abusefiltercheckmatch: Check if user can see log details
CVE-2024-PENDING

Why:
* The 'abusefiltercheckmatch' API allows callers to match
  arbitary filter conditions against existing AbuseFilter logs
* The API does not check if the performer has the ability to
  see the log details for the given filter, so can allow a user
  to bypass hidden and protected visibility settings.

What:
* Call AbuseFilterPermissionManager::canSeeLogDetailsForFilter
  before attempting to match a filter against a given AbuseFilter
  log.
* Add a test to verify that this security fix works.

Bug: T372998
Change-Id: I4a2467dc4e0d1f8401d5428a89c7f6d6ebcdfa70
2024-10-01 00:18:55 +01:00
STran 51381f0067 Bugfix: Fix minor issues with protected vars logging
- Fix an issue where if a user didn't have view permissions they could
  get the preference check error (a preference they wouldn't have) on
  SpecialAbuseLog
- Fix an issue where the `change-access` hadn't been updated to the used
  disabled/enabled log types
- Fix an issue where a ProtectedVarsAccessLoggerTest test wasn't
  correctly using the data provider data
- Improve naming since ProtectedVarsAccessLogger exists in its own test
  file instead of being a subset of tests on AbuseLoggerTest

Bug: T371798
Change-Id: I53f22855e63d9e1339361a5c9ee7886e0f74714a
2024-09-23 03:42:41 -07:00
STran 0b3d0b3b6d Write protected variables access logs to CheckUser if installed
Write logs related to temporary accounts to CheckUser if the extension
is available so that logs are topically centralized.

Bug: T373525
Depends-On: I35d50df7cd6754e29d964cc716fb3c42406272df
Change-Id: Ic95f211f4db7ce6dc2d769d2f3af206f4a3935e4
2024-09-18 07:59:05 -07:00
jenkins-bot 2ef2257922 Merge "Log changes to protected variables access" 2024-09-13 12:49:19 +00:00
jenkins-bot 4f272aeb02 Merge "Add preference for viewing protected variables in AbuseFilter" 2024-09-13 12:27:36 +00:00
STran cbfaaa591d Log changes to protected variables access
Similar to how CheckUser logs access to IP information about temporary
accounts, AbuseFilter needs to log whenever protected variables are
accessed.

- Implement ProtectedVarsAccessLogger which handles access logging
- Log whenever a user changes their ability to access protected
  variables via Special:Preferences

Bug: T371798
Change-Id: Ic7024d9c5f369eb33c4198a59638de9a1d58b04b
2024-09-13 01:39:09 -07:00
STran bd819b98a2 Add preference for viewing protected variables in AbuseFilter
Users need to enable a preference before gaining access to the IPs
from `user_unnamed_ip`, a protected variable.

- Add a preference that the user can check to toggle their access
- Check for the preference and the view right for logs that reveal
  protected variables on:
  + AbuseFilterViewExamine
  + SpecialAbuseLog
  + QueryAbuseLog

Bug: T371798
Change-Id: I5363380d999118982b216585ea73ee4274a6eac1
2024-09-12 07:59:24 -07:00
Umherirrender b2df776f8d tests: Use multi-row insert in AbuseFilterConsequencesTest
Small performance benefit by just one db call instead of multiple
Most test cases only use one filter, but some 2 to 4

Change-Id: I498c447e3873d2138e21541467115c9a67bb909e
2024-09-10 22:04:50 +02:00
Dreamy Jazz 7ecc204050 Expand SearchFilters.php to search by consequence
Why:
* SearchFilters.php allows the caller to search by a regex that
  is applied to the pattern.
* This script can be expanded to allow callers to specify what
  consequence should be associated with the filters that are
  outputted.

What:
* Add a 'consequence' option to the SearchFilters.php maintenance
  script, which is applied through a LIKE query on the
  af_actions column.
** This can be specified with or without the pattern option.
** Instead of making pattern required, the script now requires
   that one of consequence or pattern is provided.
* Expand the tests for the script for this new code, along with
  using the new ::expectCallToFatalError method to be able to
  test previously untestable code.

Bug: T373148
Change-Id: I1b507d8f9dc1f4cf91ee4f83ccde745eb6d46d6d
2024-08-22 22:07:37 +01:00
thiemowmde 3b9e995b3e Update comment still mentioning setMwGlobals
This was forgotten in I35c7099.

Change-Id: Ied7fce186ded40c60c580f7fc540aa0b8a239a3a
2024-08-11 17:26:10 +02:00
jenkins-bot cafb0c49e9 Merge "Remove usage of writeapi userright" 2024-08-01 21:06:48 +00:00
Fomafix 805a1e8248 Use overrideConfigValues/overrideConfigValue instead of setMwGlobals
Also use MainConfigNames.

Change-Id: I35c7099a63f8665ddf433116732a93ede8711e35
2024-07-30 15:04:40 +00:00
Bartosz Dziewoński 1c0ab3010a AbuseFilterExtensionJsonTest: Allow skipping other extension hooks
Change-Id: I1146cec2b27c964f5ed07e7da76fc7b9ec4a09c5
2024-07-28 20:08:30 +00:00
Umherirrender 6db3b3287f tests: Use LanguageFactory to create en language
Bug: T343771
Change-Id: Id2423c87c17a2f357d5e1cfeef3aeb83b6ad9a0d
2024-07-20 21:41:52 +02:00
jenkins-bot 5a18e60b76 Merge "Disallow protected variable access on AbuseFilterViewTestBatch" 2024-07-10 18:48:07 +00:00
STran 30227231f6 Disallow protected variable access on AbuseFilterViewTestBatch
A filter using a protected variable can be loaded via filter id
using testing tools even though the user might not have the right
to view protected variables. This can potentially leak PII and as
such, testing tools should check for the right before allowing
protected filters to be seen.

- Unload a filter asap if it uses protected variables and the
  requestor doesn't have viewing rights. This:
    + disallows loading of existing protected filters on page load
    + disallows testing against rules that use protected variables
    + disallows subsequent requests for protected filters (via API)

There is a known bug (see T369620) where no user feedback is
provided if an API request for a filter returns no result (typically
when no filter matches the requested id). This commit adds another
pathway to that bug (the filter exists but is protected and not
returned by the API) but does not update this UI/UX.

Bug: T364834
Change-Id: I6a572790edd743596d70c9c4a2ee52b4561e25f3
2024-07-10 05:31:03 -07:00
Kosta Harlan b58d91bcac ConfirmEditHandlerTest: Loosen message check test
Why:

- Ie13181b78b8e2903c6cc0f0f778689bcc8b8ce2e modifies the status message
  returned

What:

- Loosen the check for the status error message such that 'captcha-edit'
  and 'captcha-edit-fail' are both valid; we can revert this after
  Ie13181b78b8e2903c6cc0f0f778689bcc8b8ce2e is merged

Change-Id: I5a0698d84932a474800a68dba9b76b3433b19290
2024-07-10 08:20:18 +00:00
jenkins-bot c316be857b Merge "ConfirmEditHandlerTest: Remove method_exists checks" 2024-07-09 11:32:25 +00:00
jenkins-bot 218627233b Merge "Only return filters visible to user in search" 2024-07-09 09:45:55 +00:00
Kosta Harlan 62629ec3e9
ConfirmEditHandlerTest: Remove method_exists checks
Why:

- These checks are no longer needed, now that Idc47bda has been merged

What:

- Remove the `method_exists()` checks

Change-Id: I6e428df6b6e036146ae4cc57374cde8810d3f5f7
2024-07-09 10:27:03 +02:00
jenkins-bot 98eab47d9b Merge "Simplify FilterEvaluator::getUsedVars using ::checkSyntax" 2024-07-08 12:42:18 +00:00
STran ceaedb8b95 Only return filters visible to user in search
Search is restricted to users with the right to view private variables
but not necessarily the right to view protected variables. Users who
don't have the right to view protected variables shouldn't be able to
search against protected variables, as this might leak the PII.

- Filter out filters using protected variables in search results
  if the user doesn't have the right to view protected variables

Bug: T367390
Change-Id: I7412112c9cc676f29d706b116b779bc17183a952
2024-07-08 02:47:57 -07:00
jenkins-bot 69508bf153 Merge "Add missing permission check to canSeeLogDetailsForFilter" 2024-07-05 10:09:47 +00:00
Matěj Suchánek bf180e0490 Simplify FilterEvaluator::getUsedVars using ::checkSyntax
Alternative approach to fixing the regression proposed by
Daimona in I78d3a2cd7bada962d7ef9b0f2c39d898bf8987ce.

Bug: T368203
Change-Id: I637367c3b3850f7988d890379fef7f4753159953
2024-07-05 11:32:09 +02:00
Daimona Eaytoy 99bb44beb4 Miscellaneous minor fixes
- Rename `$hidden` to `$privacyLevel` in Flags::__construct for
  consistency with other places.
- Rename `shouldProtectFilter` and simplify its return value to always
  be an array, since that's how it's currently used. Rename a variable
  that is assigned the return value of this method.
- Add a missing message key to a list of dynamic message keys.
- Rename a property from 'hidden' to 'privacy' in FilterStoreTest for
  consistency. Add a test for removing the protected flag.
- Update old comment referencing `filterHidden`; the method was removed
  in I40b8c8452d9df.
- Use ISQLPlatform::bitAnd() instead of manual SQL in
  AbuseFilterHistoryPager.
- Update mysterious reference to "formatRow" in SpecialAbuseLog.
- Update other references to the very same method in two other places,
  this time credited as "SpecialAbuseLog".
- Add type hints to a few methods; this not only helps with type safety,
  but it also allows PHPUnit to automatically use the proper type in
  mocks.

Change-Id: Ib0167d993b761271c1e5311808435a616b6576fe
2024-07-03 02:31:38 +02:00
Daimona Eaytoy 6ac574dada Add missing permission check to canSeeLogDetailsForFilter
`canSeeLogDetails` should also be checked when a filter is protected, as
it is the base right for being able to see abuselog entries. With this
in mind, check that immediately at the beginning of the method, instead
of repeating calls. Also merge the conditionals, and return early when a
permission check fails.

Move a test up so that it comes immediately after its data provider, and
add test cases for a few combinations of rights.

Change-Id: Ic3cf58f43803bef8bf2d65566434baff145b3fd5
2024-07-02 22:43:09 +02:00
Wandji69 6a091dcb39 Tests: Repalce "db" with getDb() method
Bug: T316841
Change-Id: I40eb000f008e51aba581ee8e33a8421ff111fbf1
2024-06-28 16:32:16 +00:00
Jakob Warkotsch 9fc29beb09 Reset setForceShowCaptcha to false after test
This test globally set `setForceShowCaptcha` to true, which caused
problems for following tests.

Bug: T368705
Change-Id: I5077e4b874c1bf1c6b68895349af0c9ecd4094ed
2024-06-28 12:15:49 +02:00
Kosta Harlan b93543ef00 ConfirmEditHandler: Use SimpleCaptcha API to invoke CAPTCHA display
Why:

- The previous attempt to integrate AbuseFilter with ConfirmEdit set
  a flag on the request object
  (I110a5f5321649dcf85993a0c209ab70b9886057c) didn't work in WMF
  production because in WMF, we load ConfirmEdit first, followed by
  AbuseFilter. Therefore any flag set in an AbuseFilter hook is ignored
  by ConfirmEdit

What:

- Remove implementation of ConfirmEditTriggersCaptchaHook, as this does
  not work when AbuseFilter is loaded after ConfirmEdit.
- Repurpose onConfirmEditTriggersCaptcha to handle non-edit actions only
- Implement the EditFilterMergedContent hook and call SimpleCaptcha's
  public confirmEditMerged method if CaptchaConsequence has specified
  that a CAPTCHA should be displayed, and if the CAPTCHA has not already
  been solved

Soft-Depends-On: Idc47bdae8007da938f31e1c0f33e9be4813f41d7
Bug: T20110
Change-Id: I7dd3a7c41606dcf5123518c2d3d0f4355f5edfd3
2024-06-26 16:07:40 +00:00
Bartosz Dziewoński 0a83eb9b5d FilterValidatorTest: Use MediaWiki core status assertions
Depends-On: Ie4b3ebc03abb0e352e82394ced6ab9e733c83fb4
Depends-On: I8718cf7890f05c09a6e5712ee3dc4d171a6637cf
Change-Id: I6cb0cee65646b2b108319df6a9f862cbdd881691
2024-06-25 20:44:51 +00:00
jenkins-bot 72ab79dcd1 Merge "Remove AbuseFilterActorMigration" 2024-06-20 15:44:49 +00:00
jenkins-bot bb026443dd Merge "Drop af_user(_text) and afh_user(_text) fields" 2024-06-17 12:25:54 +00:00
Matěj Suchánek cb08d684d5 Remove AbuseFilterActorMigration
Bug: T188180
Change-Id: Idcacc9f63075b621bbc858a461dc6fb7ab7a9a39
Depends-On: I7dd5fc0f9d80636b0cdf3d995fe22c1f43a5b68d
Depends-On: Ibdb2b4096f26fc6752456a05f8d70a9a6d9609ad
2024-06-15 09:42:27 +02:00
Umherirrender c3af3157b4 Use namespaced classes
Changes to the use statements done automatically via script
Addition of missing use statement done manually

Change-Id: I48fcc02c61d423c9c5111ae545634fdc5c5cc710
2024-06-12 20:01:35 +02:00