Merge pull request #7986 from JakubOnderka/better-security

chg: [internal] Do not modify session when not necessary
pull/8099/head
Jakub Onderka 2021-12-30 14:40:01 +01:00 committed by GitHub
commit 50d284b643
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 159 additions and 115 deletions

4
.gitmodules vendored
View File

@ -11,10 +11,6 @@
[submodule "app/files/warninglists"] [submodule "app/files/warninglists"]
path = app/files/warninglists path = app/files/warninglists
url = https://github.com/MISP/misp-warninglists.git url = https://github.com/MISP/misp-warninglists.git
[submodule "app/Lib/random_compat"]
path = app/Lib/random_compat
url = https://github.com/paragonie/random_compat
branch = master
[submodule "app/files/misp-galaxy"] [submodule "app/files/misp-galaxy"]
path = app/files/misp-galaxy path = app/files/misp-galaxy
url = https://github.com/MISP/misp-galaxy url = https://github.com/MISP/misp-galaxy

View File

@ -5,7 +5,6 @@ App::uses('AppController', 'Controller');
class AllowedlistsController extends AppController class AllowedlistsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'AdminCrud' 'AdminCrud'
); );

View File

@ -22,6 +22,7 @@ App::uses('BlowfishConstantPasswordHasher', 'Controller/Component/Auth');
* @property CompressedRequestHandlerComponent $CompressedRequestHandler * @property CompressedRequestHandlerComponent $CompressedRequestHandler
* @property DeprecationComponent $Deprecation * @property DeprecationComponent $Deprecation
* @property RestSearchComponent $RestSearch * @property RestSearchComponent $RestSearch
* @property BetterSecurityComponent $Security
*/ */
class AppController extends Controller class AppController extends Controller
{ {
@ -81,7 +82,9 @@ class AppController extends Controller
) )
) )
), ),
'Security', 'Security' => [
'className' => 'BetterSecurity',
],
'ACL', 'ACL',
'CompressedRequestHandler', 'CompressedRequestHandler',
'RestResponse', 'RestResponse',
@ -217,6 +220,7 @@ class AppController extends Controller
// Throw exception if JSON in request is invalid. Default CakePHP behaviour would just ignore that error. // Throw exception if JSON in request is invalid. Default CakePHP behaviour would just ignore that error.
$this->RequestHandler->addInputType('json', [$jsonDecode]); $this->RequestHandler->addInputType('json', [$jsonDecode]);
$this->Security->unlockedActions = array($this->request->action); $this->Security->unlockedActions = array($this->request->action);
$this->Security->doNotGenerateToken = true;
} }
if ( if (
@ -230,9 +234,7 @@ class AppController extends Controller
// REST authentication // REST authentication
if ($this->_isRest() || $this->_isAutomation()) { if ($this->_isRest() || $this->_isAutomation()) {
// disable CSRF for REST access // disable CSRF for REST access
if (isset($this->components['Security'])) { $this->Security->csrfCheck = false;
$this->Security->csrfCheck = false;
}
if ($this->__loginByAuthKey() === false || $this->Auth->user() === null) { if ($this->__loginByAuthKey() === false || $this->Auth->user() === null) {
if ($this->__loginByAuthKey() === null) { if ($this->__loginByAuthKey() === null) {
$this->loadModel('Log'); $this->loadModel('Log');
@ -395,8 +397,6 @@ class AppController extends Controller
private function __loginByAuthKey() private function __loginByAuthKey()
{ {
if (Configure::read('Security.authkey_keep_session') && $this->Auth->user()) { if (Configure::read('Security.authkey_keep_session') && $this->Auth->user()) {
// Do not check authkey if session is establish and correct, just close session to allow multiple requests
session_write_close();
return true; return true;
} }

View File

@ -9,7 +9,7 @@ App::uses('AttachmentTool', 'Tools');
*/ */
class AttributesController extends AppController class AttributesController extends AppController
{ {
public $components = array('Security', 'RequestHandler'); public $components = array('RequestHandler');
public $paginate = [ public $paginate = [
'limit' => 60, 'limit' => 60,
@ -47,9 +47,8 @@ class AttributesController extends AppController
$this->Security->unlockedActions[] = 'getMassEditForm'; $this->Security->unlockedActions[] = 'getMassEditForm';
$this->Security->unlockedActions[] = 'search'; $this->Security->unlockedActions[] = 'search';
if ($this->request->action === 'add_attachment') { if ($this->request->action === 'add_attachment') {
$this->Security->disabledFields = array('values'); $this->Security->unlockedFields = array('values');
} }
$this->Security->validatePost = true;
// convert uuid to id if present in the url and overwrite id field // convert uuid to id if present in the url and overwrite id field
if (isset($this->request->params->query['uuid'])) { if (isset($this->request->params->query['uuid'])) {

View File

@ -8,7 +8,6 @@ App::uses('AuditLog', 'Model');
class AuditLogsController extends AppController class AuditLogsController extends AppController
{ {
public $components = [ public $components = [
'Security',
'RequestHandler', 'RequestHandler',
]; ];

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class AuthKeysController extends AppController class AuthKeysController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'CRUD', 'CRUD',
'RequestHandler' 'RequestHandler'
); );

View File

@ -0,0 +1,84 @@
<?php
App::uses('SecurityComponent', 'Controller/Component');
/**
* @property SessionComponent $Session
*/
class BetterSecurityComponent extends SecurityComponent
{
/**
* Do not generate CSRF token. This make sense for REST calls and for calls that do not use tokens. So session
* will not be big with csrfLimit (by default 100) of token.
* @var bool
*/
public $doNotGenerateToken = false;
public function generateToken(CakeRequest $request)
{
if (isset($request->params['requested']) && $request->params['requested'] === 1) {
if ($this->Session->check('_Token')) {
$request->params['_Token'] = $this->Session->read('_Token');
}
return false;
}
if ($this->doNotGenerateToken) {
return true;
}
// No need to hash random data
$authKey = bin2hex(Security::randomBytes(16));
$token = array(
'key' => $authKey,
'allowedControllers' => $this->allowedControllers,
'allowedActions' => $this->allowedActions,
'unlockedFields' => array_merge($this->disabledFields, $this->unlockedFields),
'csrfTokens' => array(),
);
if ($this->Session->check('_Token')) {
$tokenData = $this->Session->read('_Token');
if (!empty($tokenData['csrfTokens']) && is_array($tokenData['csrfTokens'])) {
$token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
}
}
if ($this->csrfUseOnce || empty($token['csrfTokens'])) {
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
}
if (!$this->csrfUseOnce) {
$csrfTokens = array_keys($token['csrfTokens']);
$authKey = $csrfTokens[0];
$token['key'] = $authKey;
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
}
$this->Session->write('_Token', $token);
$request->params['_Token'] = array(
'key' => $token['key'],
'unlockedFields' => $token['unlockedFields'],
);
return true;
}
/**
* Avoid possible timing attacks by using `hash_equals` method to compare hashes.
* @param Controller $controller
* @return bool
*/
protected function _validatePost(Controller $controller)
{
$token = $this->_validToken($controller);
$hashParts = $this->_hashParts($controller);
$check = sha1(implode('', $hashParts));
if (hash_equals($token, $check)) {
return true;
}
$msg = self::DEFAULT_EXCEPTION_MESSAGE;
if (Configure::read('debug')) {
$msg = $this->_debugPostTokenNotMatching($controller, $hashParts);
}
throw new AuthSecurityException($msg);
}
}

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class CorrelationExclusionsController extends AppController class CorrelationExclusionsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'CRUD', 'CRUD',
'RequestHandler' 'RequestHandler'
); );

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/ */
class CorrelationsController extends AppController class CorrelationsController extends AppController
{ {
public $components = array('Security', 'RequestHandler'); public $components = array('RequestHandler');
public function top() public function top()
{ {

View File

@ -154,6 +154,7 @@ class DashboardsController extends AppController
throw new MethodNotAllowedException(__('This endpoint can only be reached via POST requests.')); throw new MethodNotAllowedException(__('This endpoint can only be reached via POST requests.'));
} }
$user = $this->Auth->user();
@session_write_close(); // allow concurrent AJAX requests (session hold lock by default) @session_write_close(); // allow concurrent AJAX requests (session hold lock by default)
if (empty($this->request->data['data'])) { if (empty($this->request->data['data'])) {
@ -164,10 +165,10 @@ class DashboardsController extends AppController
} }
$value = $this->request->data['data']; $value = $this->request->data['data'];
$valueConfig = json_decode($value['config'], true); $valueConfig = json_decode($value['config'], true);
$dashboardWidget = $this->Dashboard->loadWidget($this->Auth->user(), $value['widget']); $dashboardWidget = $this->Dashboard->loadWidget($user, $value['widget']);
$redis = $this->Dashboard->setupRedis(); $redis = $this->Dashboard->setupRedis();
$org_scope = $this->_isSiteAdmin() ? 0 : $this->Auth->user('org_id'); $org_scope = $this->_isSiteAdmin() ? 0 : $user['org_id'];
$lookup_hash = hash('sha256', $value['widget'] . $value['config']); $lookup_hash = hash('sha256', $value['widget'] . $value['config']);
$cacheKey = 'misp:dashboard:' . $org_scope . ':' . $lookup_hash; $cacheKey = 'misp:dashboard:' . $org_scope . ':' . $lookup_hash;
$data = $redis->get($cacheKey); $data = $redis->get($cacheKey);
@ -175,7 +176,7 @@ class DashboardsController extends AppController
$dashboardWidget->cacheLifetime = false; $dashboardWidget->cacheLifetime = false;
} }
if (empty($dashboardWidget->cacheLifetime) || empty($data)) { if (empty($dashboardWidget->cacheLifetime) || empty($data)) {
$data = $dashboardWidget->handler($this->Auth->user(), $valueConfig); $data = $dashboardWidget->handler($user, $valueConfig);
if (!empty($dashboardWidget->cacheLifetime)) { if (!empty($dashboardWidget->cacheLifetime)) {
$redis->setex($cacheKey, $dashboardWidget->cacheLifetime, json_encode(array('data' => $data))); $redis->setex($cacheKey, $dashboardWidget->cacheLifetime, json_encode(array('data' => $data)));
} }

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class DecayingModelController extends AppController class DecayingModelController extends AppController
{ {
public $components = array('Security' ,'RequestHandler'); public $components = array('RequestHandler');
public $paginate = array( public $paginate = array(
'limit' => 50, 'limit' => 50,

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class DecayingModelMappingController extends AppController class DecayingModelMappingController extends AppController
{ {
public $components = array('Security' ,'RequestHandler'); public $components = array('RequestHandler');
public $paginate = array( public $paginate = array(
'limit' => 50, 'limit' => 50,

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class EventGraphController extends AppController class EventGraphController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'RequestHandler' 'RequestHandler'
); );

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class EventReportsController extends AppController class EventReportsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'AdminCrud', 'AdminCrud',
'RequestHandler' 'RequestHandler'
); );

View File

@ -9,10 +9,8 @@ App::uses('Xml', 'Utility');
class EventsController extends AppController class EventsController extends AppController
{ {
public $components = array( public $components = array(
'Security', 'RequestHandler',
'Email', 'IOCImport',
'RequestHandler',
'IOCImport',
); );
public $paginate = array( public $paginate = array(
@ -108,6 +106,10 @@ class EventsController extends AppController
} }
$this->paginate = Set::merge($this->paginate, array('conditions' => $conditions)); $this->paginate = Set::merge($this->paginate, array('conditions' => $conditions));
} }
if ($this->request->action === 'checkLocks') {
$this->Security->doNotGenerateToken = true;
}
} }
/** /**
@ -4467,21 +4469,21 @@ class EventsController extends AppController
return new CakeResponse(array('body' => json_encode($json), 'status' => 200, 'type' => 'json')); return new CakeResponse(array('body' => json_encode($json), 'status' => 200, 'type' => 'json'));
} }
private function genDistributionGraph($id, $type = 'event', $extended = 0) private function genDistributionGraph($id, $type = 'event', $extended = 0, $user = null)
{ {
$validTools = array('event'); $validTools = array('event');
if (!in_array($type, $validTools)) { if (!in_array($type, $validTools)) {
throw new MethodNotAllowedException(__('Invalid type.')); throw new MethodNotAllowedException(__('Invalid type.'));
} }
App::uses('DistributionGraphTool', 'Tools');
$grapher = new DistributionGraphTool();
$this->loadModel('Server'); $this->loadModel('Server');
$servers = $this->Server->find('column', array( $servers = $this->Server->find('column', array(
'fields' => array('Server.name'), 'fields' => array('Server.name'),
)); ));
$grapher->construct($this->Event, $servers, $this->Auth->user(), $extended);
App::uses('DistributionGraphTool', 'Tools');
$user = $user ?: $this->Auth->user();
$grapher = new DistributionGraphTool($this->Event, $servers, $user, $extended);
$json = $grapher->get_distributions_graph($id); $json = $grapher->get_distributions_graph($id);
array_walk_recursive($json, function (&$item, $key) { array_walk_recursive($json, function (&$item, $key) {
@ -4523,8 +4525,12 @@ class EventsController extends AppController
public function getDistributionGraph($id, $type = 'event') public function getDistributionGraph($id, $type = 'event')
{ {
// Close session without writing changes to them.
$user = $this->Auth->user();
session_abort();
$extended = isset($this->params['named']['extended']) ? 1 : 0; $extended = isset($this->params['named']['extended']) ? 1 : 0;
$json = $this->genDistributionGraph($id, $type, $extended); $json = $this->genDistributionGraph($id, $type, $extended, $user);
return $this->RestResponse->viewData($json, 'json'); return $this->RestResponse->viewData($json, 'json');
} }
@ -5463,17 +5469,20 @@ class EventsController extends AppController
public function checkLocks($id, $timestamp) public function checkLocks($id, $timestamp)
{ {
// Close session without writing changes to them.
$user = $this->Auth->user();
session_abort();
$event = $this->Event->find('first', array( $event = $this->Event->find('first', array(
'recursive' => -1, 'recursive' => -1,
'conditions' => ['Event.id' => $id], 'conditions' => ['Event.id' => $id],
'fields' => ['Event.orgc_id', 'Event.timestamp'], 'fields' => ['Event.orgc_id', 'Event.timestamp'],
)); ));
// Return empty response if event not found or user org is not owner // Return empty response if event not found or user org is not owner
if (empty($event) || ($event['Event']['orgc_id'] != $this->Auth->user('org_id') && !$this->_isSiteAdmin())) { if (empty($event) || ($event['Event']['orgc_id'] != $user['org_id'] && !$this->_isSiteAdmin())) {
return new CakeResponse(['status' => 204]); return new CakeResponse(['status' => 204]);
} }
$user = $this->Auth->user();
$this->loadModel('EventLock'); $this->loadModel('EventLock');
$locks = $this->EventLock->checkLock($user, $id); $locks = $this->EventLock->checkLock($user, $id);

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class FeedsController extends AppController class FeedsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'CRUD', 'CRUD',
'RequestHandler' 'RequestHandler'
); // XXX ACL component ); // XXX ACL component

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/ */
class JobsController extends AppController class JobsController extends AppController
{ {
public $components = array('Security', 'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 20, 'limit' => 20,

View File

@ -5,7 +5,6 @@ App::uses('AppController', 'Controller');
class LogsController extends AppController class LogsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'RequestHandler', 'RequestHandler',
'AdminCrud' => array( 'AdminCrud' => array(
'crud' => array('index') 'crud' => array('index')

View File

@ -3,7 +3,6 @@ App::uses('AppController', 'Controller');
class ModulesController extends AppController class ModulesController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'RequestHandler' 'RequestHandler'
); );

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/ */
class ObjectReferencesController extends AppController class ObjectReferencesController extends AppController
{ {
public $components = array('Security' ,'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 20, 'limit' => 20,

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class ObjectTemplateElementsController extends AppController class ObjectTemplateElementsController extends AppController
{ {
public $components = array('Security' ,'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 60, 'limit' => 60,

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/ */
class ObjectTemplatesController extends AppController class ObjectTemplatesController extends AppController
{ {
public $components = array('Security' ,'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 60, 'limit' => 60,

View File

@ -10,7 +10,7 @@ class ObjectsController extends AppController
{ {
public $uses = 'MispObject'; public $uses = 'MispObject';
public $components = array('Security' ,'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 20, 'limit' => 20,

View File

@ -9,7 +9,6 @@ App::uses('AppController', 'Controller');
class PostsController extends AppController class PostsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'Session', 'Session',
'RequestHandler' 'RequestHandler'
); );

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class RegexpController extends AppController class RegexpController extends AppController
{ {
public $components = array('Security', 'RequestHandler', 'AdminCrud'); public $components = array('RequestHandler', 'AdminCrud');
public $paginate = array( public $paginate = array(
'limit' => 60, 'limit' => 60,

View File

@ -5,7 +5,6 @@ App::uses('AppController', 'Controller');
class RestClientHistoryController extends AppController class RestClientHistoryController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'AdminCrud', 'AdminCrud',
'RequestHandler' 'RequestHandler'
); );

View File

@ -10,7 +10,6 @@ App::uses('AppController', 'Controller');
class RolesController extends AppController class RolesController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'Session', 'Session',
'RequestHandler' 'RequestHandler'
); );

View File

@ -9,7 +9,7 @@ App::uses('SecurityAudit', 'Tools');
*/ */
class ServersController extends AppController class ServersController extends AppController
{ {
public $components = array('Security' ,'RequestHandler'); // XXX ACL component public $components = array('RequestHandler'); // XXX ACL component
public $paginate = array( public $paginate = array(
'limit' => 60, 'limit' => 60,

View File

@ -9,7 +9,7 @@ App::uses('AttachmentTool', 'Tools');
*/ */
class ShadowAttributesController extends AppController class ShadowAttributesController extends AppController
{ {
public $components = array('Acl', 'Security', 'RequestHandler', 'Email'); public $components = array('RequestHandler');
public $paginate = array( public $paginate = array(
'limit' => 60, 'limit' => 60,
@ -20,7 +20,6 @@ class ShadowAttributesController extends AppController
{ {
parent::beforeFilter(); parent::beforeFilter();
$this->set('title_for_layout', 'Proposals'); $this->set('title_for_layout', 'Proposals');
$this->Security->validatePost = true;
// convert uuid to id if present in the url, and overwrite id field // convert uuid to id if present in the url, and overwrite id field
if (isset($this->params->query['uuid'])) { if (isset($this->params->query['uuid'])) {

View File

@ -8,7 +8,6 @@ App::uses('AppController', 'Controller');
class TagCollectionsController extends AppController class TagCollectionsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'AdminCrud', 'AdminCrud',
'RequestHandler' 'RequestHandler'
); );

View File

@ -6,7 +6,7 @@ App::uses('AppController', 'Controller');
*/ */
class TagsController extends AppController class TagsController extends AppController
{ {
public $components = array('Security' ,'RequestHandler'); public $components = array('RequestHandler');
public $paginate = array( public $paginate = array(
'limit' => 50, 'limit' => 50,

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class TasksController extends AppController class TasksController extends AppController
{ {
public $components = array('Security' ,'RequestHandler', 'Session'); public $components = array('RequestHandler', 'Session');
public $paginate = array( public $paginate = array(
'limit' => 20, 'limit' => 20,

View File

@ -4,7 +4,7 @@ App::uses('AppController', 'Controller');
class TemplateElementsController extends AppController class TemplateElementsController extends AppController
{ {
public $components = array('Security' ,'RequestHandler'); public $components = array('RequestHandler');
public $paginate = array( public $paginate = array(
'limit' => 50, 'limit' => 50,

View File

@ -6,7 +6,7 @@ App::uses('File', 'Utility');
class TemplatesController extends AppController class TemplatesController extends AppController
{ {
public $components = array('Security' ,'RequestHandler', 'CRUD'); public $components = array('RequestHandler', 'CRUD');
public $paginate = array( public $paginate = array(
'limit' => 50, 'limit' => 50,

View File

@ -7,7 +7,6 @@ App::uses('AppController', 'Controller');
class ThreadsController extends AppController class ThreadsController extends AppController
{ {
public $components = array( public $components = array(
'Security',
'RequestHandler', 'RequestHandler',
'Session', 'Session',
); );

View File

@ -9,9 +9,7 @@ class UsersController extends AppController
public $newkey; public $newkey;
public $components = array( public $components = array(
'Security', 'RequestHandler'
'Email',
'RequestHandler'
); );
public $paginate = array( public $paginate = array(
@ -1822,6 +1820,7 @@ class UsersController extends AppController
// shows some statistics about the instance // shows some statistics about the instance
public function statistics($page = 'data') public function statistics($page = 'data')
{ {
$user = $this->Auth->user();
@session_write_close(); // loading this page can take long time, so we can close session @session_write_close(); // loading this page can take long time, so we can close session
if (!$this->_isRest()) { if (!$this->_isRest()) {
@ -1843,7 +1842,7 @@ class UsersController extends AppController
} }
if ($page === 'data') { if ($page === 'data') {
$result = $this->__statisticsData($this->params['named']); $result = $this->__statisticsData($user, $this->params['named']);
} elseif ($page === 'orgs') { } elseif ($page === 'orgs') {
if (!$this->_isSiteAdmin() && !empty(Configure::read('Security.hide_organisation_index_from_users'))) { if (!$this->_isSiteAdmin() && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
throw new MethodNotAllowedException('This feature is currently disabled.'); throw new MethodNotAllowedException('This feature is currently disabled.');
@ -1860,9 +1859,9 @@ class UsersController extends AppController
$this->render('statistics_histogram'); $this->render('statistics_histogram');
} }
} elseif ($page === 'sightings') { } elseif ($page === 'sightings') {
$result = $this->__statisticsSightings($this->params['named']); $result = $this->__statisticsSightings($user, $this->params['named']);
} elseif ($page === 'galaxyMatrix') { } elseif ($page === 'galaxyMatrix') {
$result = $this->__statisticsGalaxyMatrix($this->params['named']); $result = $this->__statisticsGalaxyMatrix($user, $this->params['named']);
} else { } else {
throw new NotFoundException("Invalid page"); throw new NotFoundException("Invalid page");
} }
@ -1872,7 +1871,7 @@ class UsersController extends AppController
} }
} }
private function __statisticsData($params = array()) private function __statisticsData(array $user, $params = array())
{ {
// set all of the data up for the heatmaps // set all of the data up for the heatmaps
$params = array( $params = array(
@ -1881,8 +1880,8 @@ class UsersController extends AppController
'conditions' => array(), 'conditions' => array(),
'order' => ['name'], 'order' => ['name'],
); );
if (!$this->_isSiteAdmin() && !empty(Configure::read('Security.hide_organisation_index_from_users'))) { if (!$user['Role']['perm_site_admin'] && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
$params['conditions'] = array('Organisation.id' => $this->Auth->user('org_id')); $params['conditions'] = array('Organisation.id' => $user['org_id']);
} }
$orgs = $this->User->Organisation->find('list', $params); $orgs = $this->User->Organisation->find('list', $params);
@ -1907,9 +1906,7 @@ class UsersController extends AppController
$stats['attribute_count_month'] = $this->User->Event->Attribute->find('count', array('conditions' => array('Attribute.timestamp >' => $this_month, 'Attribute.deleted' => 0), 'recursive' => -1)); $stats['attribute_count_month'] = $this->User->Event->Attribute->find('count', array('conditions' => array('Attribute.timestamp >' => $this_month, 'Attribute.deleted' => 0), 'recursive' => -1));
$stats['attributes_per_event'] = round($stats['attribute_count'] / $stats['event_count']); $stats['attributes_per_event'] = round($stats['attribute_count'] / $stats['event_count']);
$this->loadModel('Correlation'); $stats['correlation_count'] = $this->User->Event->Attribute->Correlation->find('count', array('recursive' => -1));
$this->Correlation->recursive = -1;
$stats['correlation_count'] = $this->Correlation->find('count', array('recursive' => -1));
$stats['correlation_count'] = $stats['correlation_count'] / 2; $stats['correlation_count'] = $stats['correlation_count'] / 2;
$stats['proposal_count'] = $this->User->Event->ShadowAttribute->find('count', array('recursive' => -1, 'conditions' => array('deleted' => 0))); $stats['proposal_count'] = $this->User->Event->ShadowAttribute->find('count', array('recursive' => -1, 'conditions' => array('deleted' => 0)));
@ -1946,10 +1943,10 @@ class UsersController extends AppController
$this->render('statistics_data'); $this->render('statistics_data');
} }
private function __statisticsSightings($params = array()) private function __statisticsSightings(array $user, $params = array())
{ {
$this->loadModel('Sighting'); $this->loadModel('Sighting');
$conditions = ['Sighting.org_id' => $this->Auth->user('org_id')]; $conditions = ['Sighting.org_id' => $user['org_id']];
if (isset($params['timestamp'])) { if (isset($params['timestamp'])) {
$conditions['Sighting.date_sighting >'] = $params['timestamp']; $conditions['Sighting.date_sighting >'] = $params['timestamp'];
} }
@ -1999,7 +1996,6 @@ class UsersController extends AppController
private function __statisticsOrgs($params = array()) private function __statisticsOrgs($params = array())
{ {
$this->loadModel('Organisation');
$conditions = array(); $conditions = array();
if (!isset($params['scope']) || $params['scope'] == 'local') { if (!isset($params['scope']) || $params['scope'] == 'local') {
$params['scope'] = 'local'; $params['scope'] = 'local';
@ -2007,12 +2003,12 @@ class UsersController extends AppController
} elseif ($params['scope'] == 'external') { } elseif ($params['scope'] == 'external') {
$conditions['Organisation.local'] = 0; $conditions['Organisation.local'] = 0;
} }
$orgs = $this->Organisation->find('all', array( $orgs = $this->User->Organisation->find('all', array(
'recursive' => -1, 'recursive' => -1,
'conditions' => $conditions, 'conditions' => $conditions,
'fields' => array('id', 'name', 'description', 'local', 'contacts', 'type', 'sector', 'nationality'), 'fields' => array('id', 'name', 'description', 'local', 'contacts', 'type', 'sector', 'nationality'),
)); ));
$orgs = Set::combine($orgs, '{n}.Organisation.id', '{n}.Organisation'); $orgs = array_column(array_column($orgs, 'Organisation'), null, 'id');
$users = $this->User->find('all', array( $users = $this->User->find('all', array(
'group' => 'User.org_id', 'group' => 'User.org_id',
'conditions' => array('User.org_id' => array_keys($orgs)), 'conditions' => array('User.org_id' => array_keys($orgs)),
@ -2170,7 +2166,7 @@ class UsersController extends AppController
} }
} }
private function __statisticsGalaxyMatrix($params = array()) private function __statisticsGalaxyMatrix(array $user, $params = array())
{ {
$this->loadModel('Event'); $this->loadModel('Event');
$this->loadModel('Galaxy'); $this->loadModel('Galaxy');
@ -2186,7 +2182,7 @@ class UsersController extends AppController
'fields' => ['id', 'name'], 'fields' => ['id', 'name'],
)); ));
foreach ($organisations as $id => $foo) { foreach ($organisations as $id => $foo) {
if (!$this->User->Organisation->canSee($this->Auth->user(), $id)) { if (!$this->User->Organisation->canSee($user, $id)) {
unset($organisations[$id]); unset($organisations[$id]);
} }
} }
@ -2225,7 +2221,7 @@ class UsersController extends AppController
} }
$elementCounter = 0; $elementCounter = 0;
$renderView = ''; $renderView = '';
$final = $this->Event->restSearch($this->Auth->user(), 'attack', $filters, false, false, $elementCounter, $renderView); $final = $this->Event->restSearch($user, 'attack', $filters, false, false, $elementCounter, $renderView);
$final = json_decode($final, true); $final = json_decode($final, true);
if (!empty($final)) { if (!empty($final)) {

View File

@ -11,7 +11,7 @@ class DistributionGraphTool
/** @var array */ /** @var array */
private $__serverList; private $__serverList;
public function construct(Event $eventModel, array $servers, array $user, $extended_view=0) public function __construct(Event $eventModel, array $servers, array $user, $extended_view=0)
{ {
$this->__eventModel = $eventModel; $this->__eventModel = $eventModel;
$this->__serverList = $servers; $this->__serverList = $servers;
@ -33,8 +33,6 @@ class DistributionGraphTool
]; ];
} }
$this->__json['distributionInfo'][5] = ""; // inherit event. Will be deleted afterward $this->__json['distributionInfo'][5] = ""; // inherit event. Will be deleted afterward
return true;
} }
private function __fetchAndAddDistributionInfo($elem) private function __fetchAndAddDistributionInfo($elem)

View File

@ -2,16 +2,6 @@
class RandomTool class RandomTool
{ {
public function __construct()
{
// import compatibility library for PHP < 7.0
if (!function_exists('random_int')) {
if (file_exists(APP . 'Lib' . DS . 'random_compat' . DS . 'lib' . DS . 'random.php')) {
require_once(APP . 'Lib' . DS . 'random_compat' . DS . 'lib' . DS . 'random.php');
}
}
}
/** /**
* Generate a random string * Generate a random string
* *
@ -27,24 +17,19 @@ class RandomTool
* @param int $length - How long should our random string be? * @param int $length - How long should our random string be?
* @param string $charset - A string of all possible characters to choose from * @param string $charset - A string of all possible characters to choose from
* @return string * @return string
* @throws Exception
*/ */
public function random_str($crypto_secure = true, $length = 32, $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') public function random_str($crypto_secure = true, $length = 32, $charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{ {
// Type checks: // Type checks:
if (!is_bool($crypto_secure)) { if (!is_bool($crypto_secure)) {
throw new InvalidArgumentException( throw new InvalidArgumentException('random_str - Argument 1 - expected a boolean');
'random_str - Argument 1 - expected a boolean'
);
} }
if (!is_numeric($length)) { if (!is_numeric($length)) {
throw new InvalidArgumentException( throw new InvalidArgumentException('random_str - Argument 2 - expected an integer');
'random_str - Argument 2 - expected an integer'
);
} }
if (!is_string($charset)) { if (!is_string($charset)) {
throw new InvalidArgumentException( throw new InvalidArgumentException('random_str - Argument 3 - expected a string');
'random_str - Argument 3 - expected a string'
);
} }
if ($length < 1) { if ($length < 1) {
@ -53,25 +38,18 @@ class RandomTool
} }
// Remove duplicate characters from $charset // Remove duplicate characters from $charset
$split = str_split($charset); $charset = count_chars($charset, 3);
$charset = implode('', array_unique($split));
// This is the maximum index for all of the characters in the string $charset // This is the maximum index for all of the characters in the string $charset
$charset_max = strlen($charset) - 1; $charset_max = strlen($charset) - 1;
if ($charset_max < 1) { if ($charset_max < 1) {
// Avoid letting users do: random_str($int, 'a'); -> 'aaaaa...' // Avoid letting users do: random_str($int, 'a'); -> 'aaaaa...'
throw new LogicException( throw new LogicException('random_str - Argument 3 - expected a string that contains at least 2 distinct characters');
'random_str - Argument 3 - expected a string that contains at least 2 distinct characters'
);
} }
// Now that we have good data, this is the meat of our function: // Now that we have good data, this is the meat of our function:
$random_str = ''; $random_str = '';
for ($i = 0; $i < $length; ++$i) { for ($i = 0; $i < $length; ++$i) {
if ($crypto_secure && function_exists('random_int')) { $r = $crypto_secure ? random_int(0, $charset_max) : mt_rand(0, $charset_max);
$r = random_int(0, $charset_max);
} else {
$r = mt_rand(0, $charset_max);
}
$random_str .= $charset[$r]; $random_str .= $charset[$r];
} }
return $random_str; return $random_str;

@ -1 +0,0 @@
Subproject commit 088c04e2f261c33bed6ca5245491cfca69195ccf

View File

@ -41,7 +41,6 @@ class Dashboard extends AppModel
$subDirectories = $customdir->read(); $subDirectories = $customdir->read();
$found = false; $found = false;
foreach ($subDirectories[0] as $subDir) { foreach ($subDirectories[0] as $subDir) {
$currentDir = new Folder(APP . 'Lib/Dashboard/' . $subDir);
if (file_exists(APP . 'Lib/Dashboard/Custom/' . $subDir . '/' . $name . '.php')) { if (file_exists(APP . 'Lib/Dashboard/Custom/' . $subDir . '/' . $name . '.php')) {
App::uses($name, 'Dashboard/Custom/' . $subDir); App::uses($name, 'Dashboard/Custom/' . $subDir);
$found = true; $found = true;