Changeset View
Changeset View
Standalone View
Standalone View
src/aphront/configuration/AphrontApplicationConfiguration.php
Show First 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | /* -( URI Routing )-------------------------------------------------------- */ | ||||
* | * | ||||
* @return pair<AphrontController,dict> Controller and dictionary of request | * @return pair<AphrontController,dict> Controller and dictionary of request | ||||
* parameters. | * parameters. | ||||
* @task routing | * @task routing | ||||
*/ | */ | ||||
final public function buildController() { | final public function buildController() { | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
// If we're configured to operate in cluster mode, reject requests which | |||||
// were not received on a cluster interface. | |||||
// | |||||
// For example, a host may have an internal address like "170.0.0.1", and | |||||
// also have a public address like "51.23.95.16". Assuming the cluster | |||||
// is configured on a range like "170.0.0.0/16", we want to reject the | |||||
// requests received on the public interface. | |||||
// | |||||
// Ideally, nodes in a cluster should only be listening on internal | |||||
// interfaces, but they may be configured in such a way that they also | |||||
// listen on external interfaces, since this is easy to forget about or | |||||
// get wrong. As a broad security measure, reject requests received on any | |||||
// interfaces which aren't on the whitelist. | |||||
$cluster_addresses = PhabricatorEnv::getEnvConfig('cluster.addresses'); | |||||
if ($cluster_addresses) { | |||||
$server_addr = idx($_SERVER, 'SERVER_ADDR'); | |||||
if (!$server_addr) { | |||||
if (php_sapi_name() == 'cli') { | |||||
// This is a command line script (probably something like a unit | |||||
// test) so it's fine that we don't have SERVER_ADDR defined. | |||||
} else { | |||||
throw new AphrontUsageException( | |||||
pht('No SERVER_ADDR'), | |||||
pht( | |||||
'Phabricator is configured to operate in cluster mode, but '. | |||||
'SERVER_ADDR is not defined in the request context. Your '. | |||||
'webserver configuration needs to forward SERVER_ADDR to '. | |||||
'PHP so Phabricator can reject requests received on '. | |||||
'external interfaces.')); | |||||
} | |||||
} else { | |||||
if (!PhabricatorEnv::isClusterAddress($server_addr)) { | |||||
throw new AphrontUsageException( | |||||
pht('External Interface'), | |||||
pht( | |||||
'Phabricator is configured in cluster mode and the address '. | |||||
'this request was received on ("%s") is not whitelisted as '. | |||||
'a cluster address.', | |||||
$server_addr)); | |||||
} | |||||
} | |||||
} | |||||
if (PhabricatorEnv::getEnvConfig('security.require-https')) { | if (PhabricatorEnv::getEnvConfig('security.require-https')) { | ||||
if (!$request->isHTTPS()) { | if (!$request->isHTTPS()) { | ||||
$https_uri = $request->getRequestURI(); | $https_uri = $request->getRequestURI(); | ||||
$https_uri->setDomain($request->getHost()); | $https_uri->setDomain($request->getHost()); | ||||
$https_uri->setProtocol('https'); | $https_uri->setProtocol('https'); | ||||
// In this scenario, we'll be redirecting to HTTPS using an absolute | // In this scenario, we'll be redirecting to HTTPS using an absolute | ||||
// URI, so we need to permit an external redirect. | // URI, so we need to permit an external redirect. | ||||
▲ Show 20 Lines • Show All 149 Lines • Show Last 20 Lines |