fix(security): content-create divi follows the Divi group switches (audit M2)
The divi input of lit/content-create is refused with unsupported when lit/divi-insert is disabled or the Divi group is disabled or read-only (ExposurePolicy::allows as a cross-group gate, asked at execute time). content-create without divi keeps working. Adds a registrar test that read-only write tools are never registered, so execute-ability can't reach them either. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -124,6 +124,7 @@ final class ExposurePolicyTest extends TestCase
|
||||
'lit/divi-outline' => 'divi',
|
||||
'lit/divi-update' => 'divi',
|
||||
'lit/divi-delete' => 'divi',
|
||||
'lit/divi-insert' => 'divi',
|
||||
'lit/media-preview' => 'media',
|
||||
'lit/media-download' => 'media',
|
||||
'lit/media-get' => 'media',
|
||||
@@ -282,4 +283,32 @@ final class ExposurePolicyTest extends TestCase
|
||||
self::assertSame('direct', $policy->mode($this->ability('lit/site-status', true)));
|
||||
self::assertSame(1, $calls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-group gate (security M2): lit/content-create's divi input follows lit/divi-insert – off
|
||||
* when that tool is disabled, its group is disabled or "nur lesen", or it does not exist.
|
||||
*/
|
||||
public function testAllowsFollowsTheNamedAbilitysMode(): void
|
||||
{
|
||||
$insert = $this->ability('lit/divi-insert', true, ['readonly' => false]);
|
||||
$others = [$this->ability('lit/divi-outline', true, ['readonly' => true]), $insert];
|
||||
|
||||
self::assertTrue((new ExposurePolicy())->withGroups(self::GROUPS)->allows('lit/divi-insert', $others));
|
||||
self::assertTrue(
|
||||
(new ExposurePolicy(['lit/divi-insert' => 'indirect']))->allows('lit/divi-insert', $others),
|
||||
'indirect still writes'
|
||||
);
|
||||
foreach (
|
||||
[
|
||||
['lit/divi-insert' => 'disabled'],
|
||||
['@group:divi' => 'disabled'],
|
||||
['@readonly:divi' => true, 'lit/divi-insert' => 'direct'],
|
||||
] as $option
|
||||
) {
|
||||
$policy = (new ExposurePolicy($option))->withGroups(self::GROUPS);
|
||||
self::assertFalse($policy->allows('lit/divi-insert', $others), (string) json_encode($option));
|
||||
}
|
||||
|
||||
self::assertFalse((new ExposurePolicy())->allows('lit/divi-insert', []), 'Divi not available');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user