Explorar el Código

Add setup check for reverse proxy header configuration

tags/v8.2beta1
Robin McCorkell hace 9 años
padre
commit
2579999373

+ 5
- 0
core/js/setupchecks.js Ver fichero

@@ -77,6 +77,11 @@
t('core', 'Your PHP version ({version}) is no longer <a href="{phpLink}">supported by PHP</a>. We encourage you to upgrade your PHP version to take advantage of performance and security updates provided by PHP.', {version: data.phpSupported.version, phpLink: 'https://secure.php.net/supported-versions.php'})
);
}
if(!data.forwardedForHeadersWorking) {
messages.push(
t('core', 'The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a href="{docLink}">documentation</a>.', {docLink: data.reverseProxyDocs})
);
}
} else {
messages.push(t('core', 'Error occurred while checking server setup'));
}

+ 61
- 5
core/js/tests/specs/setupchecksSpec.js Ver fichero

@@ -66,7 +66,12 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json'
},
JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance'})
JSON.stringify({
isUrandomAvailable: true,
serverHasInternetConnection: false,
memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
forwardedForHeadersWorking: true
})
);

async.done(function( data, s, x ){
@@ -83,7 +88,13 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json'
},
JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, dataDirectoryProtected: false, memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance'})
JSON.stringify({
isUrandomAvailable: true,
serverHasInternetConnection: false,
dataDirectoryProtected: false,
memcacheDocs: 'https://doc.owncloud.org/server/go.php?to=admin-performance',
forwardedForHeadersWorking: true
})
);

async.done(function( data, s, x ){
@@ -100,7 +111,13 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json',
},
JSON.stringify({isUrandomAvailable: true, serverHasInternetConnection: false, dataDirectoryProtected: false, isMemcacheConfigured: true})
JSON.stringify({
isUrandomAvailable: true,
serverHasInternetConnection: false,
dataDirectoryProtected: false,
isMemcacheConfigured: true,
forwardedForHeadersWorking: true
})
);

async.done(function( data, s, x ){
@@ -117,7 +134,14 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json',
},
JSON.stringify({isUrandomAvailable: false, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, dataDirectoryProtected: true, isMemcacheConfigured: true})
JSON.stringify({
isUrandomAvailable: false,
securityDocs: 'https://docs.owncloud.org/myDocs.html',
serverHasInternetConnection: true,
dataDirectoryProtected: true,
isMemcacheConfigured: true,
forwardedForHeadersWorking: true
})
);

async.done(function( data, s, x ){
@@ -126,6 +150,30 @@ describe('OC.SetupChecks tests', function() {
});
});

it('should return an error if the forwarded for headers are not working', function(done) {
var async = OC.SetupChecks.checkSetup();

suite.server.requests[0].respond(
200,
{
'Content-Type': 'application/json',
},
JSON.stringify({
isUrandomAvailable: true,
serverHasInternetConnection: true,
dataDirectoryProtected: true,
isMemcacheConfigured: true,
forwardedForHeadersWorking: false,
reverseProxyDocs: 'https://docs.owncloud.org/foo/bar.html'
})
);

async.done(function( data, s, x ){
expect(data).toEqual(['The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a href="https://docs.owncloud.org/foo/bar.html">documentation</a>.']);
done();
});
});

it('should return an error if the response has no statuscode 200', function(done) {
var async = OC.SetupChecks.checkSetup();

@@ -151,7 +199,15 @@ describe('OC.SetupChecks tests', function() {
{
'Content-Type': 'application/json',
},
JSON.stringify({isUrandomAvailable: true, securityDocs: 'https://docs.owncloud.org/myDocs.html', serverHasInternetConnection: true, dataDirectoryProtected: true, isMemcacheConfigured: true, phpSupported: {eol: true, version: '5.4.0'}})
JSON.stringify({
isUrandomAvailable: true,
securityDocs: 'https://docs.owncloud.org/myDocs.html',
serverHasInternetConnection: true,
dataDirectoryProtected: true,
isMemcacheConfigured: true,
forwardedForHeadersWorking: true,
phpSupported: {eol: true, version: '5.4.0'}
})
);

async.done(function( data, s, x ){

+ 20
- 1
settings/controller/checksetupcontroller.php Ver fichero

@@ -128,7 +128,7 @@ class CheckSetupController extends Controller {
/**
* Check if the used SSL lib is outdated. Older OpenSSL and NSS versions do
* have multiple bugs which likely lead to problems in combination with
* functionalities required by ownCloud such as SNI.
* functionality required by ownCloud such as SNI.
*
* @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
* @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
@@ -193,6 +193,23 @@ class CheckSetupController extends Controller {
return ['eol' => $eol, 'version' => PHP_VERSION];
}

/*
* Check if the reverse proxy configuration is working as expected
*
* @return bool
*/
private function forwardedForHeadersWorking() {
$trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
$remoteAddress = $this->request->getRemoteAddress();

if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
return false;
}

// either not enabled or working correctly
return true;
}

/**
* @return DataResponse
*/
@@ -207,6 +224,8 @@ class CheckSetupController extends Controller {
'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
'phpSupported' => $this->isPhpSupported(),
'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
]
);
}

+ 48
- 1
tests/settings/controller/CheckSetupControllerTest.php Ver fichero

@@ -246,7 +246,40 @@ class CheckSetupControllerTest extends TestCase {
['eol' => false, 'version' => PHP_VERSION],
self::invokePrivate($this->checkSetupController, 'isPhpSupported')
);
}

public function testForwardedForHeadersWorkingFalse() {
$this->config->expects($this->once())
->method('getSystemValue')
->with('trusted_proxies', [])
->willReturn(['1.2.3.4']);
$this->request->expects($this->once())
->method('getRemoteAddress')
->willReturn('1.2.3.4');

$this->assertFalse(
self::invokePrivate(
$this->checkSetupController,
'forwardedForHeadersWorking'
)
);
}

public function testForwardedForHeadersWorkingTrue() {
$this->config->expects($this->once())
->method('getSystemValue')
->with('trusted_proxies', [])
->willReturn(['1.2.3.4']);
$this->request->expects($this->once())
->method('getRemoteAddress')
->willReturn('4.3.2.1');

$this->assertTrue(
self::invokePrivate(
$this->checkSetupController,
'forwardedForHeadersWorking'
)
);
}

public function testCheck() {
@@ -258,6 +291,14 @@ class CheckSetupControllerTest extends TestCase {
->method('getSystemValue')
->with('memcache.local', null)
->will($this->returnValue('SomeProvider'));
$this->config->expects($this->at(2))
->method('getSystemValue')
->with('trusted_proxies', [])
->willReturn(['1.2.3.4']);

$this->request->expects($this->once())
->method('getRemoteAddress')
->willReturn('4.3.2.1');

$client = $this->getMockBuilder('\OCP\Http\Client\IClient')
->disableOriginalConstructor()->getMock();
@@ -285,6 +326,10 @@ class CheckSetupControllerTest extends TestCase {
->with('admin-security')
->willReturn('https://doc.owncloud.org/server/8.1/admin_manual/configuration_server/hardening.html');
self::$version_compare = -1;
$this->urlGenerator->expects($this->at(2))
->method('linkToDocs')
->with('admin-reverse-proxy')
->willReturn('reverse-proxy-doc-link');

$expected = new DataResponse(
[
@@ -298,7 +343,9 @@ class CheckSetupControllerTest extends TestCase {
'phpSupported' => [
'eol' => true,
'version' => PHP_VERSION
]
],
'forwardedForHeadersWorking' => true,
'reverseProxyDocs' => 'reverse-proxy-doc-link',
]
);
$this->assertEquals($expected, $this->checkSetupController->check());

Cargando…
Cancelar
Guardar