Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F58367562
T385792.patch
A_smart_kitten (a smart kitten)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Authored By
A_smart_kitten
Feb 6 2025, 1:32 PM
2025-02-06 13:32:11 (UTC+0)
Size
6 KB
Referenced Files
None
Subscribers
None
T385792.patch
View Options
From 58fd1afde529408de70bb65aefc204169c2b2364 Mon Sep 17 00:00:00 2001
From: a smart kitten <sierra-quirk-suave@duck.com>
Date: Thu, 6 Feb 2025 13:28:49 +0000
Subject: [PATCH] SECURITY: Don't add the 'Recreated' tag if the target of a
title's deletion log entry is hidden
Why:
- MediaWiki currently tags edits that create a new page at a
previously-deleted title with 'Recreated', whether or not the target
of the deletion log entry for that title has been hidden.
- However, if the target of the log events relating to a title have been
hidden, it is no longer publicly known that a page with that title
used to exist.
- Because of this, in a situation where a page is created at a title
that has previously existed but has had the targets of its log events
hidden, MediaWiki - in tagging the edit creating the new page with
'Recreated' - currently leaks the information that a page at that
title has previously existed.
What:
- Added a condition to the database query in maybeAddRecreateChangeTag()
so that it only matches deletion log entries that don't have a hidden
target (LogPage::DELETED_ACTION).
- Added a test case to check that edits are no longer tagged as
'Recreated' when the target of a title's deletion log entry has
been hidden.
- Modified existing tests to remove calls to
ManualLogEntry::setDeleted(), and edited test titles for clarity.
Bug: T385792
Change-Id: Ifb8299581e1162de35d5741b193610b09253bf9b
---
includes/Storage/DerivedPageDataUpdater.php | 11 ++++--
.../Storage/DerivedPageDataUpdaterTest.php | 35 ++++++++++++++++---
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/includes/Storage/DerivedPageDataUpdater.php b/includes/Storage/DerivedPageDataUpdater.php
index e79e2c135a4..6dfecfd4e88 100644
--- a/includes/Storage/DerivedPageDataUpdater.php
+++ b/includes/Storage/DerivedPageDataUpdater.php
@@ -25,6 +25,7 @@ use ChangeTags;
use InvalidArgumentException;
use JobQueueGroup;
use LogicException;
+use LogPage;
use MediaWiki\ChangeTags\ChangeTagsStore;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\Content\Content;
@@ -1874,14 +1875,20 @@ class DerivedPageDataUpdater implements LoggerAwareInterface, PreparedUpdate {
* @param int $revisionId
*/
private function maybeAddRecreateChangeTag( WikiPage $wikiPage, int $revisionId ) {
- if ( $this->loadbalancerFactory->getReplicaDatabase()->newSelectQueryBuilder()
+ $replicaDB = $this->loadbalancerFactory->getReplicaDatabase();
+
+ if ( $replicaDB->newSelectQueryBuilder()
->select( [ '1' ] )
->from( 'logging' )
->where( [
'log_type' => 'delete',
'log_title' => $wikiPage->getTitle()->getDBkey(),
'log_namespace' => $wikiPage->getNamespace(),
- ] )->caller( __METHOD__ )->limit( 1 )->fetchField() ) {
+ ] )
+ ->where(
+ $replicaDB->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) .
+ ' != ' . LogPage::DELETED_ACTION // T385792
+ )->caller( __METHOD__ )->limit( 1 )->fetchField() ) {
$this->changeTagsStore->addTags(
[ ChangeTags::TAG_RECREATE ],
null,
diff --git a/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php b/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
index ecd150ed1d6..7697890ec08 100644
--- a/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
+++ b/tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
@@ -1277,7 +1277,7 @@ class DerivedPageDataUpdaterTest extends MediaWikiIntegrationTestCase {
* @covers \MediaWiki\Storage\DerivedPageDataUpdater::doUpdates()
* @covers \MediaWiki\Storage\DerivedPageDataUpdater::maybeAddRecreateChangeTag
*/
- public function testDoUpdatesTagsEditAsRecreatedWhenDeletedLogEntry() {
+ public function testDoUpdatesTagsEditAsRecreatedWhenDeletionLogEntry() {
$page = $this->getPage( __METHOD__ );
$title = $this->getTitle( __METHOD__ );
@@ -1287,7 +1287,6 @@ class DerivedPageDataUpdaterTest extends MediaWikiIntegrationTestCase {
$deleteLogEntry = new ManualLogEntry( 'delete', 'delete' );
$deleteLogEntry->setPerformer( $this->getTestUser()->getUser() );
$deleteLogEntry->setTarget( $title );
- $deleteLogEntry->setDeleted( LogPage::DELETED_ACTION );
$logId = $deleteLogEntry->insert( $this->getDb() );
$deleteLogEntry->publish( $logId );
@@ -1313,7 +1312,6 @@ class DerivedPageDataUpdaterTest extends MediaWikiIntegrationTestCase {
$deleteLogEntry = new ManualLogEntry( 'delete', 'delete' );
$deleteLogEntry->setPerformer( $this->getTestUser()->getUser() );
$deleteLogEntry->setTarget( $title );
- $deleteLogEntry->setDeleted( LogPage::DELETED_ACTION );
$logId = $deleteLogEntry->insert( $this->getDb() );
$deleteLogEntry->publish( $logId );
@@ -1327,10 +1325,39 @@ class DerivedPageDataUpdaterTest extends MediaWikiIntegrationTestCase {
* @covers \MediaWiki\Storage\DerivedPageDataUpdater::doUpdates()
* @covers \MediaWiki\Storage\DerivedPageDataUpdater::maybeAddRecreateChangeTag
*/
- public function testDoUpdatesDoesNotTagEditAsRecreatedWhenNoDeletedLogEntry() {
+ public function testDoUpdatesDoesNotTagEditAsRecreatedWhenNoDeletionLogEntry() {
+ $page = $this->getPage( __METHOD__ );
+
+ $content = [ SlotRecord::MAIN => new WikitextContent( 'rev ID ver #1: {{REVISIONID}}' ) ];
+ $rev = $this->createRevision( $page, 'first', $content );
+
+ $this->assertSame( [], $this->getServiceContainer()->getChangeTagsStore()->getTags(
+ $this->getDb(), null, $rev->getId() ) );
+ }
+
+ /**
+ * See T385792
+ *
+ * @covers \MediaWiki\Storage\DerivedPageDataUpdater::doUpdates()
+ * @covers \MediaWiki\Storage\DerivedPageDataUpdater::maybeAddRecreateChangeTag
+ */
+ public function testDoUpdatesDoesNotTagEditAsRecreatedWhenDeletionLogEntryActionHidden() {
$page = $this->getPage( __METHOD__ );
+ $title = $this->getTitle( __METHOD__ );
$content = [ SlotRecord::MAIN => new WikitextContent( 'rev ID ver #1: {{REVISIONID}}' ) ];
+
+ // create a deletion log entry
+ $deleteLogEntry = new ManualLogEntry( 'delete', 'delete' );
+ $deleteLogEntry->setPerformer( $this->getTestUser()->getUser() );
+ $deleteLogEntry->setTarget( $title );
+
+ // hide the target of the deletion log entry
+ $deleteLogEntry->setDeleted( LogPage::DELETED_ACTION );
+
+ $logId = $deleteLogEntry->insert( $this->getDb() );
+ $deleteLogEntry->publish( $logId );
+
$rev = $this->createRevision( $page, 'first', $content );
$this->assertSame( [], $this->getServiceContainer()->getChangeTagsStore()->getTags(
--
2.47.1
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
19238686
Default Alt Text
T385792.patch (6 KB)
Attached To
Mode
T385792: Page recreations are tagged with 'Recreated' when the target of the deletion log entry for the previous creation has been hidden
Attached
Detach File
Event Timeline
Log In to Comment