Skip to content

Commit a1c969a

Browse files
Merge pull request #10840 from webfoersterei/refactor/5530-urandom-check
Refactor secure randomness check
2 parents 10351cb + 8d8189c commit a1c969a

File tree

4 files changed

+39
-31
lines changed

4 files changed

+39
-31
lines changed

core/js/setupchecks.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,10 @@
183183
type: OC.SetupChecks.MESSAGE_TYPE_INFO
184184
});
185185
}
186-
if(!data.isUrandomAvailable) {
186+
if(!data.isRandomnessSecure) {
187187
messages.push({
188-
msg: t('core', '/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in the <a target="_blank" rel="noreferrer noopener" href="{docLink}">documentation</a>.', {docLink: data.securityDocs}),
189-
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
188+
msg: t('core', 'No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the <a target="_blank" rel="noreferrer noopener" href="{docLink}">documentation</a>.', {docLink: data.securityDocs}),
189+
type: OC.SetupChecks.MESSAGE_TYPE_ERROR
190190
});
191191
}
192192
if(data.isUsedTlsLibOutdated) {

core/js/tests/specs/setupchecksSpec.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ describe('OC.SetupChecks tests', function() {
155155
hasWorkingFileLocking: true,
156156
hasValidTransactionIsolationLevel: true,
157157
suggestedOverwriteCliURL: '',
158-
isUrandomAvailable: true,
158+
isRandomnessSecure: true,
159159
serverHasInternetConnection: false,
160160
memcacheDocs: 'https://docs.nextcloud.com/server/go.php?to=admin-performance',
161161
forwardedForHeadersWorking: true,
@@ -204,7 +204,7 @@ describe('OC.SetupChecks tests', function() {
204204
hasWorkingFileLocking: true,
205205
hasValidTransactionIsolationLevel: true,
206206
suggestedOverwriteCliURL: '',
207-
isUrandomAvailable: true,
207+
isRandomnessSecure: true,
208208
serverHasInternetConnection: false,
209209
memcacheDocs: 'https://docs.nextcloud.com/server/go.php?to=admin-performance',
210210
forwardedForHeadersWorking: true,
@@ -254,7 +254,7 @@ describe('OC.SetupChecks tests', function() {
254254
hasWorkingFileLocking: true,
255255
hasValidTransactionIsolationLevel: true,
256256
suggestedOverwriteCliURL: '',
257-
isUrandomAvailable: true,
257+
isRandomnessSecure: true,
258258
serverHasInternetConnection: false,
259259
isMemcacheConfigured: true,
260260
forwardedForHeadersWorking: true,
@@ -301,7 +301,7 @@ describe('OC.SetupChecks tests', function() {
301301
hasWorkingFileLocking: true,
302302
hasValidTransactionIsolationLevel: true,
303303
suggestedOverwriteCliURL: '',
304-
isUrandomAvailable: false,
304+
isRandomnessSecure: false,
305305
securityDocs: 'https://docs.owncloud.org/myDocs.html',
306306
serverHasInternetConnection: true,
307307
isMemcacheConfigured: true,
@@ -325,8 +325,8 @@ describe('OC.SetupChecks tests', function() {
325325

326326
async.done(function( data, s, x ){
327327
expect(data).toEqual([{
328-
msg: '/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in the <a href="https://docs.owncloud.org/myDocs.html" rel="noreferrer noopener">documentation</a>.',
329-
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
328+
msg: 'No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the <a href="https://docs.owncloud.org/myDocs.html" rel="noreferrer noopener">documentation</a>.',
329+
type: OC.SetupChecks.MESSAGE_TYPE_ERROR
330330
}]);
331331
done();
332332
});
@@ -347,7 +347,7 @@ describe('OC.SetupChecks tests', function() {
347347
hasWorkingFileLocking: true,
348348
hasValidTransactionIsolationLevel: true,
349349
suggestedOverwriteCliURL: '',
350-
isUrandomAvailable: true,
350+
isRandomnessSecure: true,
351351
securityDocs: 'https://docs.owncloud.org/myDocs.html',
352352
serverHasInternetConnection: true,
353353
isMemcacheConfigured: true,
@@ -393,7 +393,7 @@ describe('OC.SetupChecks tests', function() {
393393
hasWorkingFileLocking: true,
394394
hasValidTransactionIsolationLevel: true,
395395
suggestedOverwriteCliURL: '',
396-
isUrandomAvailable: true,
396+
isRandomnessSecure: true,
397397
securityDocs: 'https://docs.owncloud.org/myDocs.html',
398398
serverHasInternetConnection: true,
399399
isMemcacheConfigured: true,
@@ -441,7 +441,7 @@ describe('OC.SetupChecks tests', function() {
441441
hasWorkingFileLocking: true,
442442
hasValidTransactionIsolationLevel: true,
443443
suggestedOverwriteCliURL: '',
444-
isUrandomAvailable: true,
444+
isRandomnessSecure: true,
445445
serverHasInternetConnection: true,
446446
isMemcacheConfigured: true,
447447
forwardedForHeadersWorking: false,
@@ -487,7 +487,7 @@ describe('OC.SetupChecks tests', function() {
487487
hasWorkingFileLocking: true,
488488
hasValidTransactionIsolationLevel: true,
489489
suggestedOverwriteCliURL: '',
490-
isUrandomAvailable: true,
490+
isRandomnessSecure: true,
491491
serverHasInternetConnection: true,
492492
isMemcacheConfigured: true,
493493
forwardedForHeadersWorking: true,
@@ -533,7 +533,7 @@ describe('OC.SetupChecks tests', function() {
533533
hasWorkingFileLocking: true,
534534
hasValidTransactionIsolationLevel: true,
535535
suggestedOverwriteCliURL: '',
536-
isUrandomAvailable: true,
536+
isRandomnessSecure: true,
537537
serverHasInternetConnection: true,
538538
isMemcacheConfigured: true,
539539
forwardedForHeadersWorking: true,
@@ -599,7 +599,7 @@ describe('OC.SetupChecks tests', function() {
599599
hasWorkingFileLocking: true,
600600
hasValidTransactionIsolationLevel: true,
601601
suggestedOverwriteCliURL: '',
602-
isUrandomAvailable: true,
602+
isRandomnessSecure: true,
603603
securityDocs: 'https://docs.owncloud.org/myDocs.html',
604604
serverHasInternetConnection: true,
605605
isMemcacheConfigured: true,
@@ -646,7 +646,7 @@ describe('OC.SetupChecks tests', function() {
646646
hasWorkingFileLocking: true,
647647
hasValidTransactionIsolationLevel: true,
648648
suggestedOverwriteCliURL: '',
649-
isUrandomAvailable: true,
649+
isRandomnessSecure: true,
650650
securityDocs: 'https://docs.owncloud.org/myDocs.html',
651651
serverHasInternetConnection: true,
652652
isMemcacheConfigured: true,
@@ -693,7 +693,7 @@ describe('OC.SetupChecks tests', function() {
693693
hasWorkingFileLocking: true,
694694
hasValidTransactionIsolationLevel: true,
695695
suggestedOverwriteCliURL: '',
696-
isUrandomAvailable: true,
696+
isRandomnessSecure: true,
697697
securityDocs: 'https://docs.owncloud.org/myDocs.html',
698698
serverHasInternetConnection: true,
699699
isMemcacheConfigured: true,
@@ -740,7 +740,7 @@ describe('OC.SetupChecks tests', function() {
740740
hasWorkingFileLocking: true,
741741
hasValidTransactionIsolationLevel: true,
742742
suggestedOverwriteCliURL: '',
743-
isUrandomAvailable: true,
743+
isRandomnessSecure: true,
744744
securityDocs: 'https://docs.owncloud.org/myDocs.html',
745745
serverHasInternetConnection: true,
746746
isMemcacheConfigured: true,

settings/Controller/CheckSetupController.php

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
use OCP\IRequest;
5656
use OCP\IURLGenerator;
5757
use OCP\Lock\ILockingProvider;
58+
use OCP\Security\ISecureRandom;
5859
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
5960
use Symfony\Component\EventDispatcher\GenericEvent;
6061

@@ -86,6 +87,8 @@ class CheckSetupController extends Controller {
8687
private $dateTimeFormatter;
8788
/** @var MemoryInfo */
8889
private $memoryInfo;
90+
/** @var ISecureRandom */
91+
private $secureRandom;
8992

9093
public function __construct($AppName,
9194
IRequest $request,
@@ -100,7 +103,8 @@ public function __construct($AppName,
100103
IDBConnection $db,
101104
ILockingProvider $lockingProvider,
102105
IDateTimeFormatter $dateTimeFormatter,
103-
MemoryInfo $memoryInfo) {
106+
MemoryInfo $memoryInfo,
107+
ISecureRandom $secureRandom) {
104108
parent::__construct($AppName, $request);
105109
$this->config = $config;
106110
$this->clientService = $clientService;
@@ -114,6 +118,7 @@ public function __construct($AppName,
114118
$this->lockingProvider = $lockingProvider;
115119
$this->dateTimeFormatter = $dateTimeFormatter;
116120
$this->memoryInfo = $memoryInfo;
121+
$this->secureRandom = $secureRandom;
117122
}
118123

119124
/**
@@ -167,20 +172,17 @@ private function isMemcacheConfigured() {
167172
}
168173

169174
/**
170-
* Whether /dev/urandom is available to the PHP controller
175+
* Whether PHP can generate "secure" pseudorandom integers
171176
*
172177
* @return bool
173178
*/
174-
private function isUrandomAvailable() {
175-
if(@file_exists('/dev/urandom')) {
176-
$file = fopen('/dev/urandom', 'rb');
177-
if($file) {
178-
fclose($file);
179-
return true;
180-
}
179+
private function isRandomnessSecure() {
180+
try {
181+
$this->secureRandom->generate(1);
182+
} catch (\Exception $ex) {
183+
return false;
181184
}
182-
183-
return false;
185+
return true;
184186
}
185187

186188
/**
@@ -601,7 +603,7 @@ public function check() {
601603
'serverHasInternetConnection' => $this->isInternetConnectionWorking(),
602604
'isMemcacheConfigured' => $this->isMemcacheConfigured(),
603605
'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
604-
'isUrandomAvailable' => $this->isUrandomAvailable(),
606+
'isRandomnessSecure' => $this->isRandomnessSecure(),
605607
'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
606608
'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
607609
'phpSupported' => $this->isPhpSupported(),

tests/Settings/Controller/CheckSetupControllerTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use OC;
2525
use OC\DB\Connection;
2626
use OC\MemoryInfo;
27+
use OC\Security\SecureRandom;
2728
use OC\Settings\Controller\CheckSetupController;
2829
use OCP\AppFramework\Http;
2930
use OCP\AppFramework\Http\DataDisplayResponse;
@@ -79,6 +80,8 @@ class CheckSetupControllerTest extends TestCase {
7980
private $dateTimeFormatter;
8081
/** @var MemoryInfo|MockObject */
8182
private $memoryInfo;
83+
/** @var SecureRandom|\PHPUnit_Framework_MockObject_MockObject */
84+
private $secureRandom;
8285

8386
/**
8487
* Holds a list of directories created during tests.
@@ -119,6 +122,7 @@ public function setUp() {
119122
$this->memoryInfo = $this->getMockBuilder(MemoryInfo::class)
120123
->setMethods(['isMemoryLimitSufficient',])
121124
->getMock();
125+
$this->secureRandom = $this->getMockBuilder(SecureRandom::class)->getMock();
122126
$this->checkSetupController = $this->getMockBuilder('\OC\Settings\Controller\CheckSetupController')
123127
->setConstructorArgs([
124128
'settings',
@@ -135,6 +139,7 @@ public function setUp() {
135139
$this->lockingProvider,
136140
$this->dateTimeFormatter,
137141
$this->memoryInfo,
142+
$this->secureRandom,
138143
])
139144
->setMethods([
140145
'isReadOnlyConfig',
@@ -482,7 +487,7 @@ public function testCheck() {
482487
'serverHasInternetConnection' => false,
483488
'isMemcacheConfigured' => true,
484489
'memcacheDocs' => 'http://docs.example.org/server/go.php?to=admin-performance',
485-
'isUrandomAvailable' => self::invokePrivate($this->checkSetupController, 'isUrandomAvailable'),
490+
'isRandomnessSecure' => self::invokePrivate($this->checkSetupController, 'isRandomnessSecure'),
486491
'securityDocs' => 'https://docs.example.org/server/8.1/admin_manual/configuration_server/hardening.html',
487492
'isUsedTlsLibOutdated' => '',
488493
'phpSupported' => [
@@ -528,6 +533,7 @@ public function testGetCurlVersion() {
528533
$this->lockingProvider,
529534
$this->dateTimeFormatter,
530535
$this->memoryInfo,
536+
$this->secureRandom,
531537
])
532538
->setMethods(null)->getMock();
533539

0 commit comments

Comments
 (0)