Skip to content

Commit f59ebf4

Browse files
author
epriestley
committed
Fix incorrect key handling in extended policy filtering
Summary: Via HackerOne. The use of `$key` here should be `$extended_key`. Exploiting this requires a very unusual group of objects to be subjected to extended policy checks. I believe there is no way to actually get anything bad through the policy filter today, but this could have been an issue in the future. Test Plan: - Added a unit test which snuck something through the policy filter. - Fixed use of `$extended_key`. - Test now passes. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D14993
1 parent 0b3d10c commit f59ebf4

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

src/applications/policy/__tests__/PhabricatorPolicyTestCase.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,76 @@ public function testExtendedPolicyCycles() {
285285
pht('Extended Policy with Cycle'));
286286
}
287287

288+
289+
/**
290+
* Test bulk checks of extended policies.
291+
*
292+
* This is testing an issue with extended policy filtering which allowed
293+
* unusual inputs to slip objects through the filter. See D14993.
294+
*/
295+
public function testBulkExtendedPolicies() {
296+
$object1 = $this->buildObject(PhabricatorPolicies::POLICY_USER)
297+
->setPHID('PHID-TEST-1');
298+
$object2 = $this->buildObject(PhabricatorPolicies::POLICY_USER)
299+
->setPHID('PHID-TEST-2');
300+
$object3 = $this->buildObject(PhabricatorPolicies::POLICY_USER)
301+
->setPHID('PHID-TEST-3');
302+
303+
$extended = $this->buildObject(PhabricatorPolicies::POLICY_ADMIN)
304+
->setPHID('PHID-TEST-999');
305+
306+
$object1->setExtendedPolicies(
307+
array(
308+
PhabricatorPolicyCapability::CAN_VIEW => array(
309+
array(
310+
$extended,
311+
array(
312+
PhabricatorPolicyCapability::CAN_VIEW,
313+
PhabricatorPolicyCapability::CAN_EDIT,
314+
),
315+
),
316+
),
317+
));
318+
319+
$object2->setExtendedPolicies(
320+
array(
321+
PhabricatorPolicyCapability::CAN_VIEW => array(
322+
array($extended, PhabricatorPolicyCapability::CAN_VIEW),
323+
),
324+
));
325+
326+
$object3->setExtendedPolicies(
327+
array(
328+
PhabricatorPolicyCapability::CAN_VIEW => array(
329+
array(
330+
$extended,
331+
array(
332+
PhabricatorPolicyCapability::CAN_VIEW,
333+
PhabricatorPolicyCapability::CAN_EDIT,
334+
),
335+
),
336+
),
337+
));
338+
339+
$user = $this->buildUser('user');
340+
341+
$visible = id(new PhabricatorPolicyFilter())
342+
->setViewer($user)
343+
->requireCapabilities(
344+
array(
345+
PhabricatorPolicyCapability::CAN_VIEW,
346+
))
347+
->apply(
348+
array(
349+
$object1,
350+
$object2,
351+
$object3,
352+
));
353+
354+
$this->assertEqual(array(), $visible);
355+
}
356+
357+
288358
/**
289359
* An omnipotent user should be able to see even objects with invalid
290360
* policies.
@@ -430,10 +500,12 @@ private function buildObject($policy) {
430500
$object->setCapabilities(
431501
array(
432502
PhabricatorPolicyCapability::CAN_VIEW,
503+
PhabricatorPolicyCapability::CAN_EDIT,
433504
));
434505
$object->setPolicies(
435506
array(
436507
PhabricatorPolicyCapability::CAN_VIEW => $policy,
508+
PhabricatorPolicyCapability::CAN_EDIT => $policy,
437509
));
438510

439511
return $object;

src/applications/policy/filter/PhabricatorPolicyFilter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ private function applyExtendedPolicyChecks(array $extended_objects) {
321321
$objects_in = array();
322322
foreach ($structs as $struct) {
323323
$extended_key = $struct['key'];
324-
if (empty($extended_objects[$key])) {
324+
if (empty($extended_objects[$extended_key])) {
325325
// If this object has already been rejected by an earlier filtering
326326
// pass, we don't need to do any tests on it.
327327
continue;
@@ -335,8 +335,8 @@ private function applyExtendedPolicyChecks(array $extended_objects) {
335335
// We weren't able to load the corresponding object, so just
336336
// reject this result outright.
337337

338-
$reject = $extended_objects[$key];
339-
unset($extended_objects[$key]);
338+
$reject = $extended_objects[$extended_key];
339+
unset($extended_objects[$extended_key]);
340340

341341
// TODO: This could be friendlier.
342342
$this->rejectObject($reject, false, '<bad-ref>');

0 commit comments

Comments
 (0)