fix: [security] Do not allow to fetch value of redacted setting

pull/8176/head
Jakub Onderka 2022-02-26 09:58:28 +01:00 committed by Jakub Onderka
parent 22487aec4f
commit 351d2bfa20
3 changed files with 32 additions and 23 deletions

View File

@ -1442,23 +1442,23 @@ class ServersController extends AppController
$this->render('ajax/submoduleStatus');
}
public function getSetting($setting_name)
public function getSetting($settingName)
{
$setting = $this->Server->getSettingData($setting_name);
if (!empty($setting["redacted"])) {
throw new MethodNotAllowedException(__('This setting is redacted.'));
$setting = $this->Server->getSettingData($settingName);
if (!$setting) {
throw new NotFoundException(__('Setting %s is invalid.', $settingName));
}
if (Configure::check($setting_name)) {
$setting['value'] = Configure::read($setting_name);
if (!empty($setting["redacted"])) {
throw new ForbiddenException(__('This setting is redacted.'));
}
if (Configure::check($settingName)) {
$setting['value'] = Configure::read($settingName);
}
return $this->RestResponse->viewData($setting);
}
public function serverSettingsEdit($setting_name, $id = false, $forceSave = false)
public function serverSettingsEdit($settingName, $id = false, $forceSave = false)
{
if (!isset($setting_name)) {
throw new MethodNotAllowedException();
}
if (!$this->_isRest()) {
if (!isset($id)) {
throw new MethodNotAllowedException();
@ -1466,9 +1466,9 @@ class ServersController extends AppController
$this->set('id', $id);
}
$setting = $this->Server->getSettingData($setting_name);
$setting = $this->Server->getSettingData($settingName);
if ($setting === false) {
throw new NotFoundException(__('Setting %s is invalid.', $setting_name));
throw new NotFoundException(__('Setting %s is invalid.', $settingName));
}
if (!empty($setting['cli_only'])) {
throw new MethodNotAllowedException(__('This setting can only be edited via the CLI.'));
@ -1489,7 +1489,10 @@ class ServersController extends AppController
$subGroup = 'general';
}
if ($this->_isRest()) {
return $this->RestResponse->viewData(array($setting['name'] => $setting['value']));
if (!empty($setting['redacted'])) {
throw new ForbiddenException(__('This setting is redacted.'));
}
return $this->RestResponse->viewData([$setting['name'] => $setting['value']]);
} else {
$this->set('subGroup', $subGroup);
$this->set('setting', $setting);

View File

@ -1294,8 +1294,7 @@ class Server extends AppModel
{
$serverSettings = $this->serverSettings;
$moduleTypes = array('Enrichment', 'Import', 'Export', 'Cortex');
$serverSettings = $this->readModuleSettings($serverSettings, $moduleTypes);
return $serverSettings;
return $this->readModuleSettings($serverSettings, $moduleTypes);
}
/**
@ -2156,33 +2155,32 @@ class Server extends AppModel
}
/**
* @param string $setting_name
* @param string $settingName
* @return array|false False if setting doesn't exists
*/
public function getSettingData($setting_name, $withOptions = true)
public function getSettingData($settingName, $withOptions = true)
{
// This is just hack to reset opcache, so for next request cache will be reloaded.
$this->opcacheResetConfig();
if (strpos($setting_name, 'Plugin.Enrichment') !== false || strpos($setting_name, 'Plugin.Import') !== false || strpos($setting_name, 'Plugin.Export') !== false || strpos($setting_name, 'Plugin.Cortex') !== false) {
if (strpos($settingName, 'Plugin.Enrichment') !== false || strpos($settingName, 'Plugin.Import') !== false || strpos($settingName, 'Plugin.Export') !== false || strpos($settingName, 'Plugin.Cortex') !== false) {
$serverSettings = $this->getCurrentServerSettings();
} else {
$serverSettings = $this->serverSettings;
}
$setting = $serverSettings;
$parts = explode('.', $setting_name);
$parts = explode('.', $settingName);
foreach ($parts as $part) {
if (isset($setting[$part])) {
$setting = $setting[$part];
} else {
$setting = false;
break;
return false;
}
}
if (isset($setting['level'])) {
$setting['name'] = $setting_name;
$setting['name'] = $settingName;
if ($withOptions && isset($setting['optionsSource'])) {
$setting['options'] = $setting['optionsSource']();
}

View File

@ -13,7 +13,7 @@ logging.disable(logging.CRITICAL)
logger = logging.getLogger('pymisp')
from pymisp import PyMISP, MISPOrganisation, MISPUser, MISPRole, MISPSharingGroup, MISPEvent, MISPLog, MISPSighting, Distribution, ThreatLevel, Analysis, MISPEventReport
from pymisp import PyMISP, MISPOrganisation, MISPUser, MISPRole, MISPSharingGroup, MISPEvent, MISPLog, MISPSighting, Distribution, ThreatLevel, Analysis, MISPEventReport, MISPServerError
# Load access information for env variables
url = "http://" + os.environ["HOST"]
@ -641,6 +641,14 @@ class TestComprehensive(unittest.TestCase):
})
self.assertEqual(204, response.status_code)
def test_redacted_setting(self):
response = self.admin_misp_connector.get_server_setting('Security.salt')
self.assertEqual(403, response["errors"][0])
response = self.admin_misp_connector._prepare_request('GET', 'servers/serverSettingsEdit/Security.salt')
response = self.admin_misp_connector._check_json_response(response)
self.assertEqual(403, response["errors"][0])
def _search(self, query: dict):
response = self.admin_misp_connector._prepare_request('POST', 'events/restSearch', data=query)
response = self.admin_misp_connector._check_response(response)