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 | |||||