@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Prevent locked credentials from being made accessible via conduit

Summary:
Via HackerOne. Currently, you can use "Lock Permanently" to lock a credential permanently, but you can still enable Conduit API access to it. This directly contradicts both intent of the setting and its description as presented to the user.

Instead:

- When a credential is locked, revoke Conduit API access.
- Prevent API access from being enabled for locked credentials.
- Prevent API access to locked credentials, period.

Test Plan:
- Created a credential.
- Enabled API access.
- Locked credential.
- Saw API access become disabled.
- Tried to enable API access; was rebuffed.
- Queried credential via API, wasn't granted access.

Reviewers: chad

Reviewed By: chad

Differential Revision: https://secure.phabricator.com/D15944

+42 -20
+5 -2
src/applications/passphrase/conduit/PassphraseQueryConduitAPIMethod.php
··· 63 63 64 64 $material = array(); 65 65 66 + $is_locked = $credential->getIsLocked(); 67 + $allow_api = ($credential->getAllowConduit() && !$is_locked); 68 + 66 69 $secret = null; 67 70 if ($request->getValue('needSecrets')) { 68 - if ($credential->getAllowConduit()) { 71 + if ($allow_api) { 69 72 $secret = $credential->getSecret(); 70 73 if ($secret) { 71 74 $secret = $secret->openEnvelope(); ··· 102 105 break; 103 106 } 104 107 105 - if (!$credential->getAllowConduit()) { 108 + if (!$allow_api) { 106 109 $material['noAPIAccess'] = pht( 107 110 'This private material for this credential is not accessible via '. 108 111 'API calls.');
+14
src/applications/passphrase/controller/PassphraseCredentialConduitController.php
··· 33 33 throw new Exception(pht('Credential has invalid type "%s"!', $type)); 34 34 } 35 35 36 + $is_locked = $credential->getIsLocked(); 37 + 38 + if ($is_locked) { 39 + return $this->newDialog() 40 + ->setUser($viewer) 41 + ->setTitle(pht('Credential Locked')) 42 + ->appendChild( 43 + pht( 44 + 'This credential can not be made available via Conduit because '. 45 + 'it is locked.')) 46 + ->addCancelButton($view_uri); 47 + } 48 + 36 49 if ($request->isFormPost()) { 37 50 $xactions = array(); 51 + 38 52 $xactions[] = id(new PassphraseCredentialTransaction()) 39 53 ->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) 40 54 ->setNewValue(!$credential->getAllowConduit());
+8 -9
src/applications/passphrase/controller/PassphraseCredentialEditController.php
··· 270 270 } 271 271 272 272 if ($type->shouldRequireUsername()) { 273 - $form 274 - ->appendChild( 273 + $form->appendChild( 275 274 id(new AphrontFormTextControl()) 276 275 ->setName('username') 277 276 ->setLabel(pht('Login/Username')) ··· 279 278 ->setDisabled($credential_is_locked) 280 279 ->setError($e_username)); 281 280 } 282 - $form 283 - ->appendChild( 284 - $secret_control 285 - ->setName('secret') 286 - ->setLabel($type->getSecretLabel()) 287 - ->setDisabled($credential_is_locked) 288 - ->setValue($v_secret)); 281 + 282 + $form->appendChild( 283 + $secret_control 284 + ->setName('secret') 285 + ->setLabel($type->getSecretLabel()) 286 + ->setDisabled($credential_is_locked) 287 + ->setValue($v_secret)); 289 288 290 289 if ($type->shouldShowPasswordField()) { 291 290 $form->appendChild(
+12 -8
src/applications/passphrase/controller/PassphraseCredentialLockController.php
··· 32 32 return $this->newDialog() 33 33 ->setTitle(pht('Credential Already Locked')) 34 34 ->appendChild( 35 - pht( 36 - 'This credential has been locked and the secret is '. 37 - 'hidden forever. Anything relying on this credential will '. 38 - 'still function. This operation can not be undone.')) 35 + pht('This credential is already locked.')) 39 36 ->addCancelButton($view_uri, pht('Close')); 40 37 } 41 38 42 39 if ($request->isFormPost()) { 43 40 $xactions = array(); 41 + 42 + $xactions[] = id(new PassphraseCredentialTransaction()) 43 + ->setTransactionType(PassphraseCredentialTransaction::TYPE_CONDUIT) 44 + ->setNewValue(0); 45 + 44 46 $xactions[] = id(new PassphraseCredentialTransaction()) 45 47 ->setTransactionType(PassphraseCredentialTransaction::TYPE_LOCK) 46 48 ->setNewValue(1); ··· 48 50 $editor = id(new PassphraseCredentialTransactionEditor()) 49 51 ->setActor($viewer) 50 52 ->setContinueOnMissingFields(true) 53 + ->setContinueOnNoEffect(true) 51 54 ->setContentSourceFromRequest($request) 52 55 ->applyTransactions($credential, $xactions); 53 56 ··· 55 58 } 56 59 57 60 return $this->newDialog() 58 - ->setTitle(pht('Really lock credential?')) 61 + ->setTitle(pht('Lock Credential')) 59 62 ->appendChild( 60 63 pht( 61 - 'This credential will be locked and the secret will be '. 62 - 'hidden forever. Anything relying on this credential will '. 63 - 'still function. This operation can not be undone.')) 64 + 'This credential will be locked and the secret will be hidden '. 65 + 'forever. If Conduit access is enabled, it will be revoked. '. 66 + 'Anything relying on this credential will still function. This '. 67 + 'operation can not be undone.')) 64 68 ->addSubmitButton(pht('Lock Credential')) 65 69 ->addCancelButton($view_uri); 66 70 }
+3 -1
src/applications/passphrase/controller/PassphraseCredentialViewController.php
··· 119 119 $credential, 120 120 PhabricatorPolicyCapability::CAN_EDIT); 121 121 122 + $can_conduit = ($can_edit && !$is_locked); 123 + 122 124 $curtain = $this->newCurtainView($credential); 123 125 124 126 $curtain->addAction( ··· 161 163 ->setName($credential_conduit_text) 162 164 ->setIcon($credential_conduit_icon) 163 165 ->setHref($this->getApplicationURI("conduit/{$id}/")) 164 - ->setDisabled(!$can_edit) 166 + ->setDisabled(!$can_conduit) 165 167 ->setWorkflow(true)); 166 168 167 169 $curtain->addAction(