Api: Fix permission checks in action=compare

Why:
- action=compare was used to circumvent Lockdown

What:
- use checkTitleUserPermissions() to enforce read permissions in
  ApiComparePages.

Bug: T397521
Change-Id: Id275382743957004fa7fc56318fc104d8e2d267b
(cherry picked from commit c62e4d93a33e94c7fe6f716a4747b1dbd59b3f90)
This commit is contained in:
daniel 2025-06-20 20:14:49 +02:00 committed by SBassett
parent 7f1fa6f51f
commit db6013aa6c
2 changed files with 52 additions and 0 deletions

View file

@ -279,9 +279,18 @@ class ApiComparePages extends ApiBase {
*/
private function getRevisionById( $id ) {
$rev = $this->revisionStore->getRevisionById( $id );
if ( $rev ) {
$this->checkTitleUserPermissions( $rev->getPage(), 'read' );
}
if ( !$rev && $this->getAuthority()->isAllowedAny( 'deletedtext', 'undelete' ) ) {
// Try the 'archive' table
$rev = $this->archivedRevisionLookup->getArchivedRevisionRecord( null, $id );
if ( $rev ) {
$this->checkTitleUserPermissions( $rev->getPage(), 'deletedtext' );
}
}
return $rev;
}

View file

@ -1073,4 +1073,47 @@ class ApiComparePagesTest extends ApiTestCase {
];
// phpcs:enable
}
/**
* Assert that read access restrictions are enforced (T397521).
*/
public function testNoReadAccess() {
$this->overrideConfigValue( MainConfigNames::DiffEngine, 'php' );
$params = [
'fromrev' => '{{REPL:revA2}}',
'torelative' => 'cur',
'prop' => 'ids',
'action' => 'compare',
'errorformat' => 'none',
];
$this->doReplacements( $params );
$performer = static::getTestUser()->getAuthority();
// Emulate access restrictions as implemented by Lockdown and similar
// extensions.
$this->setTemporaryHook(
'getUserPermissionsErrors',
static function ( $title, $user, $action, &$result ) {
if ( $action === 'read' ) {
$result = 'badaccess-group0';
return false;
}
return true;
}
);
$expectedCode = 'permissiondenied';
try {
$this->doApiRequest( $params, null, false, $performer );
$this->fail( 'Expected exception not thrown' );
} catch ( ApiUsageException $ex ) {
$this->assertApiErrorCode( $expectedCode, $ex,
"Exception with code $expectedCode" );
}
}
}