mirror of https://github.com/MISP/MISP
new: Added new feature to block attributes from IDS sensitive exports based on proposals
- Enabled via a new server setting (MISP.proposals_block_attributes) - Attributes are skipped from exports that require the to_ids flag if: - they have an active proposal that proposes to remove the to_ids flag - they have an active proposal that proposes to delete the attribute - Currently affected exports: - OpenIOC - All HIDS exports - All NIDS exports - All text exports - RPZ Zone file exportpull/1637/head
parent
97512bd092
commit
ebdaa11312
|
@ -1868,7 +1868,9 @@ class AttributesController extends AppController {
|
|||
$this->header('Content-Disposition: download; filename="misp.rpz.' . $file . 'txt"');
|
||||
$this->layout = 'text/default';
|
||||
$this->loadModel('Whitelist');
|
||||
$values = $this->Whitelist->removeWhitelistedValuesFromArray($values);
|
||||
foreach ($values as $key => $value) {
|
||||
$values[$key] = $this->Whitelist->removeWhitelistedValuesFromArray($value);
|
||||
}
|
||||
$this->set('values', $values);
|
||||
$this->set('rpzSettings', $rpzSettings);
|
||||
$this->render('/Attributes/rpz');
|
||||
|
|
|
@ -1317,7 +1317,7 @@ class Attribute extends AppModel {
|
|||
public function text($user, $type, $tags = false, $eventId = false, $allowNonIDS = false, $from = false, $to = false, $last = false) {
|
||||
//restricting to non-private or same org if the user is not a site-admin.
|
||||
$conditions['AND'] = array();
|
||||
if ($allowNonIDS === false) $conditions['AND'] = array('Attribute.to_ids =' => 1, 'Event.published =' => 1);
|
||||
if ($allowNonIDS === false) $conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
|
||||
if ($type !== 'all') $conditions['AND']['Attribute.type'] = $type;
|
||||
if ($from) $conditions['AND']['Event.date >='] = $from;
|
||||
if ($to) $conditions['AND']['Event.date <='] = $to;
|
||||
|
@ -1378,13 +1378,12 @@ class Attribute extends AppModel {
|
|||
}
|
||||
$values = array();
|
||||
foreach ($typesToFetch as $k => $v) {
|
||||
$tempConditions = $conditions;
|
||||
$tempConditions['type'] = $v;
|
||||
$temp = $this->fetchAttributes(
|
||||
$user,
|
||||
array(
|
||||
'conditions' => array(
|
||||
$conditions,
|
||||
array('type' => $v),
|
||||
),
|
||||
'conditions' => $tempConditions,
|
||||
'fields' => array('Attribute.value'), // array of field names
|
||||
)
|
||||
);
|
||||
|
@ -1413,7 +1412,7 @@ class Attribute extends AppModel {
|
|||
|
||||
function bro($user, $type, $tags = false, $eventId = false, $from = false, $to = false, $last = false) {
|
||||
//restricting to non-private or same org if the user is not a site-admin.
|
||||
$conditions['AND'] = array('Attribute.to_ids =' => 1, 'Event.published =' => 1);
|
||||
$conditions['AND'] = array('Attribute.to_ids' => 1, 'Event.published' => 1);
|
||||
if ($from) $conditions['AND']['Event.date >='] = $from;
|
||||
if ($to) $conditions['AND']['Event.date <='] = $to;
|
||||
if ($last) $conditions['AND']['Event.publish_timestamp >='] = $last;
|
||||
|
@ -1799,6 +1798,24 @@ class Attribute extends AppModel {
|
|||
);
|
||||
if (isset($options['contain'])) $params['contain'] = array_merge_recursive($params['contain'], $options['contain']);
|
||||
else $option['contain']['Event']['fields'] = array('id', 'info', 'org_id', 'orgc_id');
|
||||
if (Configure::read('MISP.proposals_block_attributes') && isset($options['conditions']['AND']['Attribute.to_ids']) && $options['conditions']['AND']['Attribute.to_ids'] == 1) {
|
||||
$this->bindModel(array('hasMany' => array('ShadowAttribute' => array('foreignKey' => 'old_id'))));
|
||||
$proposalRestriction = array(
|
||||
'ShadowAttribute' => array(
|
||||
'conditions' => array(
|
||||
'AND' => array(
|
||||
'ShadowAttribute.deleted' => 0,
|
||||
'OR' => array(
|
||||
'ShadowAttribute.proposal_to_delete' => 1,
|
||||
'ShadowAttribute.to_ids' => 0
|
||||
)
|
||||
)
|
||||
),
|
||||
'fields' => array('ShadowAttribute.id')
|
||||
)
|
||||
);
|
||||
$params['contain'] = array_merge($params['contain'], $proposalRestriction);
|
||||
}
|
||||
if (isset($options['fields'])) $params['fields'] = $options['fields'];
|
||||
if (isset($options['conditions'])) $params['conditions']['AND'][] = $options['conditions'];
|
||||
if (isset($options['order'])) $params['order'] = $options['order'];
|
||||
|
@ -1807,6 +1824,16 @@ class Attribute extends AppModel {
|
|||
if (isset($options['group'])) $params['group'] = array_merge(array('Attribute.id'), $options['group']);
|
||||
if (Configure::read('MISP.unpublishedprivate')) $params['conditions']['AND'][] = array('OR' => array('Event.published' => 1, 'Event.orgc_id' => $user['org_id']));
|
||||
$results = $this->find('all', $params);
|
||||
if (Configure::read('MISP.proposals_block_attributes')) {
|
||||
foreach ($results as $key => $value) {
|
||||
if (!empty($value['ShadowAttribute'])) {
|
||||
unset($results[$key]);
|
||||
} else {
|
||||
unset($results[$key]['ShadowAttribute']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$results = array_values($results);
|
||||
if (isset($options['withAttachments']) && $options['withAttachments']) {
|
||||
foreach ($results as &$attribute) {
|
||||
if ($this->typeIsAttachment($attribute['Attribute']['type'])) {
|
||||
|
|
|
@ -1325,19 +1325,19 @@ class Event extends AppModel {
|
|||
$results[$eventKey]['RelatedAttribute'] = $this->getRelatedAttributes($user, $event['Event']['id'], $sgsids);
|
||||
$results[$eventKey]['RelatedShadowAttribute'] = $this->getRelatedAttributes($user, $event['Event']['id'], $sgsids, true);
|
||||
if (isset($event['ShadowAttribute']) && !empty($event['ShadowAttribute']) && isset($options['includeAttachments']) && $options['includeAttachments']) {
|
||||
foreach ($event['ShadowAttribute'] as &$sa) {
|
||||
foreach ($event['ShadowAttribute'] as $k => $sa) {
|
||||
if ($this->ShadowAttribute->typeIsAttachment($sa['type'])) {
|
||||
$encodedFile = $this->ShadowAttribute->base64EncodeAttachment($sa);
|
||||
$sa['data'] = $encodedFile;
|
||||
$event['ShadowAttribute'][$k]['data'] = $encodedFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($event['Attribute'])) {
|
||||
foreach ($event['Attribute'] as $key => &$attribute) {
|
||||
foreach ($event['Attribute'] as $key => $attribute) {
|
||||
if (isset($options['includeAttachments']) && $options['includeAttachments']) {
|
||||
if ($this->Attribute->typeIsAttachment($attribute['type'])) {
|
||||
$encodedFile = $this->Attribute->base64EncodeAttachment($attribute);
|
||||
$attribute['data'] = $encodedFile;
|
||||
$event['Attribute'][$key]['data'] = $encodedFile;
|
||||
}
|
||||
}
|
||||
if (isset($attribute['SharingGroup']['SharingGroupServer'])) {
|
||||
|
@ -1347,18 +1347,28 @@ class Event extends AppModel {
|
|||
}
|
||||
}
|
||||
}
|
||||
$attribute['ShadowAttribute'] = array();
|
||||
$event['Attribute'][$key]['ShadowAttribute'] = array();
|
||||
// If a shadowattribute can be linked to an attribute, link it to it then remove it from the event
|
||||
// This is to differentiate between proposals that were made to an attribute for modification and between proposals for new attributes
|
||||
foreach ($event['ShadowAttribute'] as $k => &$sa) {
|
||||
foreach ($event['ShadowAttribute'] as $k => $sa) {
|
||||
if (!empty($sa['old_id'])) {
|
||||
if ($sa['old_id'] == $attribute['id']) {
|
||||
if ($event['ShadowAttribute'][$k]['old_id'] == $attribute['id']) {
|
||||
$results[$eventKey]['Attribute'][$key]['ShadowAttribute'][] = $sa;
|
||||
unset($results[$eventKey]['ShadowAttribute'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Configure::read('MISP.proposals_block_attributes') && isset($options['to_ids']) && $options['to_ids']) {
|
||||
foreach ($results[$eventKey]['Attribute'][$key]['ShadowAttribute'] as $sa) {
|
||||
if ($sa['proposal_to_delete'] || $sa['to_ids'] == 0) {
|
||||
unset($results[$eventKey]['Attribute'][$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$event['Attribute'] = array_values($event['Attribute']);
|
||||
}
|
||||
if (Configure::read('Plugin.Sightings_enable')) {
|
||||
$event['Sighting'] = $this->Sighting->attachToEvent($event, $user);
|
||||
|
@ -1366,10 +1376,10 @@ class Event extends AppModel {
|
|||
// remove proposals to attributes that we cannot see
|
||||
// if the shadow attribute wasn't moved within an attribute before, this is the case
|
||||
if (isset($event['ShadowAttribute'])) {
|
||||
$event['ShadowAttribute'] = array_values($event['ShadowAttribute']);
|
||||
foreach ($event['ShadowAttribute'] as $k => &$sa) {
|
||||
foreach ($event['ShadowAttribute'] as $k => $sa) {
|
||||
if (!empty($sa['old_id'])) unset($event['ShadowAttribute'][$k]);
|
||||
}
|
||||
$event['ShadowAttribute'] = array_values($event['ShadowAttribute']);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
|
@ -1380,11 +1390,11 @@ class Event extends AppModel {
|
|||
$conditions = array();
|
||||
// If we are not in the search result csv download function then we need to check what can be downloaded. CSV downloads are already filtered by the search function.
|
||||
if ($eventid !== 'search') {
|
||||
if ($from) $conditions['AND'][] = array('Event.date >=' => $from);
|
||||
if ($to) $conditions['AND'][] = array('Event.date <=' => $to);
|
||||
if ($last) $conditions['AND'][] = array('Event.publish_timestamp >=' => $last);
|
||||
if ($from) $conditions['AND']['Event.date >='] = $from;
|
||||
if ($to) $conditions['AND']['Event.date <='] = $to;
|
||||
if ($last) $conditions['AND']['Event.publish_timestamp >='] = $last;
|
||||
// This is for both single event downloads and for full downloads. Org has to be the same as the user's or distribution not org only - if the user is no siteadmin
|
||||
if ($ignore == false) $conditions['AND'][] = array('Event.published' => 1);
|
||||
if ($ignore == false) $conditions['AND']['Event.published'] = 1;
|
||||
|
||||
// If we sent any tags along, load the associated tag names for each attribute
|
||||
if ($tags) {
|
||||
|
@ -1406,9 +1416,9 @@ class Event extends AppModel {
|
|||
if ($eventid) $conditions['AND'][] = array('Event.id' => $eventid);
|
||||
|
||||
//restricting to non-private or same org if the user is not a site-admin.
|
||||
if (!$ignore) $conditions['AND'][] = array('Attribute.to_ids' => 1);
|
||||
if ($type) $conditions['AND'][] = array('Attribute.type' => $type);
|
||||
if ($category) $conditions['AND'][] = array('Attribute.category' => $category);
|
||||
if (!$ignore) $conditions['AND']['Attribute.to_ids'] = 1;
|
||||
if ($type) $conditions['AND']['Attribute.type'] = $type;
|
||||
if ($category) $conditions['AND']['Attribute.category'] = $category;
|
||||
}
|
||||
|
||||
if ($eventid === 'search') {
|
||||
|
|
|
@ -654,6 +654,15 @@ class Server extends AppModel {
|
|||
'type' => 'string',
|
||||
'null' => true,
|
||||
),
|
||||
'proposals_block_attributes' => array(
|
||||
'level' => 0,
|
||||
'description' => 'Enable this setting to allow blocking attributes from to_ids sensitive exports if a proposal has been made to it to remove the IDS flag or to remove the attribute altogether. This is a powerful tool to deal with false-positives efficiently.',
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => false,
|
||||
)
|
||||
),
|
||||
'GnuPG' => array(
|
||||
'branch' => 1,
|
||||
|
|
Loading…
Reference in New Issue