Merge branch 'develop' into 2.4

pull/9615/head v2.4.187
iglocska 2024-03-07 15:05:10 +01:00
commit 661b238b3f
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
25 changed files with 315 additions and 51 deletions

2
PyMISP

@ -1 +1 @@
Subproject commit 4715f91d2ab948fb44640426be6a40099f94c910
Subproject commit 601e534778817d19bdda5227df983c1766ad10cd

View File

@ -1 +1 @@
{"major":2, "minor":4, "hotfix":186}
{"major":2, "minor":4, "hotfix":187}

View File

@ -0,0 +1,64 @@
<?php
/**
* @property User $User
* @property Log $Log
* @property UserLoginProfile $UserLoginProfile
*/
class OrganisationShell extends AppShell
{
public $uses = ['Organisation'];
public function getOptionParser()
{
$parser = parent::getOptionParser();
$parser->addSubcommand('list', [
'help' => __('Get list of organisations.'),
'parser' => [
'arguments' => [
'filter' => ['help' => __('Filter the list by name.'), 'required' => false],
'local' => ['help' => __('Filter the list by local/known organisations.'), 'required' => false],
],
'options' => [
'json' => ['help' => __('Output as JSON.'), 'boolean' => true],
],
]
]);
return $parser;
}
public function list()
{
$filter = $this->args[0] ?? null;
$local = isset($this->args[1]) ? $this->args[1] : null;
$conditions = [];
if ($filter) {
$conditions = ['OR' => [
'Organisation.name LIKE' => "%$filter%",
'Organisation.uuid LIKE' => "%$filter%"
]];
}
if ($local !== null) {
$conditions['OR'][] = [
'Organisation.local' => $local
];
}
$organisations = $this->Organisation->find('all', [
'recursive' => -1,
'conditions' => $conditions
]);
if ($this->params['json']) {
$this->out($this->json($organisations));
} else {
foreach ($organisations as $organisation) {
$this->out(sprintf(
'%d. [%s] %s',
$organisation['Organisation']['id'],
$organisation['Organisation']['uuid'],
$organisation['Organisation']['name']
));
}
$this->out(count($organisations) . ' hits.');
}
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* @property User $User
* @property Log $Log
* @property UserLoginProfile $UserLoginProfile
*/
class RoleShell extends AppShell
{
public $uses = ['Role'];
public function getOptionParser()
{
$parser = parent::getOptionParser();
$parser->addSubcommand('list', [
'help' => __('Get list of the roles.'),
'parser' => [
'arguments' => [
'filter' => ['help' => __('Filter list by name.'), 'required' => false],
],
'options' => [
'json' => ['help' => __('Output as JSON.'), 'boolean' => true],
],
]
]);
return $parser;
}
public function list()
{
$filter = $this->args[0] ?? null;
if ($filter) {
$conditions = ['OR' => [
'Role.name LIKE' => "%$filter%"
]];
} else {
$conditions = [];
}
$roles = $this->Role->find('all', [
'recursive' => -1,
'conditions' => $conditions
]);
if ($this->params['json']) {
$this->out($this->json($roles));
} else {
foreach ($roles as $role) {
$this->out(sprintf(
'%d. %s',
$role['Role']['id'],
$role['Role']['name']
));
}
}
$this->out(count($roles) . ' hits.');
}
}

View File

@ -16,7 +16,21 @@ class UserShell extends AppShell
'help' => __('Get list of user accounts.'),
'parser' => [
'arguments' => [
'userId' => ['help' => __('User ID or e-mail address.'), 'required' => true],
'userId' => ['help' => __('User ID or e-mail address to filter.'), 'required' => false],
],
'options' => [
'json' => ['help' => __('Output as JSON.'), 'boolean' => true],
],
]
]);
$parser->addSubcommand('create', [
'help' => __('Create a new user account.'),
'parser' => [
'arguments' => [
'email' => ['help' => __('E-mail address (also used as the username.'), 'required' => true],
'role_id' => ['help' => __('Role ID of the user. For a list of available roles, use `cake Roles list`.'), 'required' => true],
'org_id' => ['help' => __('Organisation under which the user should be created'), 'required' => true],
'password' => ['help' => __('Enter a password to assign to the user (optional) - if none is set, the user will receive a temporary password.')]
],
'options' => [
'json' => ['help' => __('Output as JSON.'), 'boolean' => true],
@ -82,6 +96,15 @@ class UserShell extends AppShell
],
],
]);
$parser->addSubcommand('change_role', [
'help' => __('Change user role.'),
'parser' => [
'arguments' => [
'userId' => ['help' => __('User ID or e-mail address.'), 'required' => true],
'new_role' => ['help' => __('Role ID or Role name.'), 'required' => true],
]
],
]);
$parser->addSubcommand('change_authkey', [
'help' => __('Change authkey. When advanced authkeys are enabled, old authkeys will be disabled.'),
'parser' => [
@ -180,6 +203,48 @@ class UserShell extends AppShell
}
}
public function create()
{
if (empty($this->args[0]) || empty($this->args[1]) || empty($this->args[2])) {
$this->err('Invalid input. Usage: `User create [email] [role_id] [org_id] [password:optional]`');
}
$user = [
'email' => $this->args[0],
'role_id' => $this->args[1],
'org_id' => $this->args[2],
'change_pw' => true
];
if (!empty($this->args[3])) {
$user['password'] = $this->args[3];
$user['confirm_password'] = $this->args[3];
$user['change_pw'] = true;
}
$this->User->create();
$result = $this->User->save($user);
// do not fetch sensitive or big values
$schema = $this->User->schema();
unset($schema['authkey']);
unset($schema['password']);
unset($schema['gpgkey']);
unset($schema['certif_public']);
$fields = array_keys($schema);
$fields[] = 'Role.*';
$fields[] = 'Organisation.*';
$user = $this->User->find('first', [
'recursive' => -1,
'fields' => $fields,
'conditions' => ['User.id' => $this->User->id],
'contain' => ['Organisation', 'Role', 'UserSetting'],
]);
if ($this->params['json']) {
$this->out($this->json($user));
} else {
$this->out('User created.');
}
}
public function init()
{
if (!Configure::read('Security.salt')) {
@ -443,6 +508,35 @@ class UserShell extends AppShell
}
}
public function change_role()
{
list($userId, $newRole) = $this->args;
$user = $this->getUser($userId);
if (is_numeric($newRole)) {
$conditions = ['Role.id' => $newRole];
} else {
$conditions = ['Role.name' => $newRole];
}
$newRoleFromDb = $this->User->Role->find('first', [
'conditions' => $conditions,
'fields' => ['Role.id'],
]);
if (empty($newRoleFromDb)) {
$this->error("Role `$newRole` not found.");
}
if ($newRoleFromDb['Role']['id'] == $user['role_id']) {
$this->error("Role `$newRole` is already assigned to {$user['email']}.");
}
$this->User->updateField($user, 'role_id', $newRoleFromDb['Role']['id']);
$this->out("Role changed from `{$user['role_id']}` to `{$newRoleFromDb['Role']['id']}`.");
}
public function user_ips()
{
list($userId) = $this->args;
@ -575,7 +669,7 @@ class UserShell extends AppShell
}
/**
* @param string|int $userId
* @param string|int $userId User ID or User e-mail
* @return array
*/
private function getUser($userId)

View File

@ -34,7 +34,7 @@ class AppController extends Controller
public $helpers = array('OrgImg', 'FontAwesome', 'UserName');
private $__queryVersion = '159';
public $pyMispVersion = '2.4.186';
public $pyMispVersion = '2.4.187';
public $phpmin = '7.2';
public $phprec = '7.4';
public $phptoonew = '8.0';

View File

@ -2369,7 +2369,13 @@ class EventsController extends AppController
}
$isXml = $ext === 'xml';
$data = FileAccessTool::readFromFile($file['tmp_name'], $file['size']);
$matches = null;
$tmp_name = $file['tmp_name'];
if (preg_match_all('/[\w\/\-\.]*/', $tmp_name, $matches) && file_exists($file['tmp_name'])) {
$data = FileAccessTool::readFromFile($matches[0][0], $file['size']);
} else {
throw new NotFoundException(__('Invalid file.'));
}
} else {
throw new MethodNotAllowedException(__('No file uploaded.'));
}
@ -2378,7 +2384,6 @@ class EventsController extends AppController
&& (isset($this->request->data['Event']['takeownership']) && $this->request->data['Event']['takeownership'] == 1);
$publish = $this->request->data['Event']['publish'] ?? false;
try {
$results = $this->Event->addMISPExportFile($this->Auth->user(), $data, $isXml, $takeOwnership, $publish);
} catch (Exception $e) {

View File

@ -202,7 +202,7 @@ class GalaxiesController extends AppController
}
$result = $this->Galaxy->save($galaxy);
if ($result) {
$message = __('Galaxy enabled');
$message = __('Galaxy %s', $enabled ? __('enabled') : __('disabled'));
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('Galaxy', 'toggle', false, $this->response->type(), $message);
} else {

View File

@ -490,8 +490,14 @@ class OrganisationsController extends AppController
$this->Flash->error(__('Invalid file extension, Only PNG and SVG images are allowed.'));
return false;
}
$imgMime = mime_content_type($logo['tmp_name']);
$matches = null;
$tmp_name = $logo['tmp_name'];
if (preg_match_all('/[\w\/\-\.]*/', $tmp_name, $matches) && file_exists($logo['tmp_name'])) {
$tmp_name = $matches[0][0];
$imgMime = mime_content_type($tmp_name);
} else {
throw new NotFoundException(__('Invalid file.'));
}
if ($extension === 'png' && (function_exists('exif_imagetype') && !exif_imagetype($logo['tmp_name']))) {
$this->Flash->error(__('This is not a valid PNG image.'));
return false;
@ -507,8 +513,8 @@ class OrganisationsController extends AppController
return false;
}
if (!empty($logo['tmp_name']) && is_uploaded_file($logo['tmp_name'])) {
return move_uploaded_file($logo['tmp_name'], APP . 'files/img/orgs/' . $filename);
if (!empty($tmp_name) && is_uploaded_file($tmp_name)) {
return move_uploaded_file($tmp_name, APP . 'files/img/orgs/' . $filename);
}
}

View File

@ -820,6 +820,15 @@ class TagsController extends AppController
}
$message = 'Global tag ' . $existingTag['Tag']['name'] . '(' . $existingTag['Tag']['id'] . ') successfully attached to ' . $objectType . '(' . $object[$objectType]['id'] . ').';
}
$this->loadModel('Log');
$this->Log->createLogEntry(
$this->Auth->user(),
'attachTagToObject',
$objectType,
$object[$objectType]['id'],
$message,
null
);
$successes++;
} else {
$fails[] = __('Failed to attach tag to object.');
@ -896,6 +905,17 @@ class TagsController extends AppController
$result = $this->$objectType->$connectorObject->delete($existingAssociation[$connectorObject]['id']);
if ($result) {
$message = __('%s tag %s (%s) successfully removed from %s(%s).', $local ? __('Local') : __('Global'), $existingTag['Tag']['name'], $existingTag['Tag']['id'], $objectType, $object[$objectType]['id']);
$this->loadModel('Log');
$this->Log->createLogEntry(
$this->Auth->user(),
'removeTagFromObject',
$objectType,
$object[$objectType]['id'],
$message,
__(
'',
)
);
if (!$local) {
if ($objectType === 'Attribute') {
$this->Attribute->touch($object['Attribute']['id']);

View File

@ -217,7 +217,7 @@ class ServerSyncTool
}
/**
* @param array $rules
* @param array $candidates
* @return HttpSocketResponseExtended
* @throws HttpSocketHttpException
* @throws HttpSocketJsonException
@ -225,7 +225,7 @@ class ServerSyncTool
public function filterAnalystDataForPush(array $candidates)
{
if (!$this->isSupported(self::PERM_ANALYST_DATA)) {
return [];
throw new RuntimeException("Remote server do not support analyst data");
}
return $this->post('/analyst_data/filterAnalystDataForPush', $candidates);
@ -240,20 +240,23 @@ class ServerSyncTool
public function fetchIndexMinimal(array $rules)
{
if (!$this->isSupported(self::PERM_ANALYST_DATA)) {
return [];
throw new RuntimeException("Remote server do not support analyst data");
}
return $this->post('/analyst_data/indexMinimal', $rules);
}
/**
* @param string $type
* @param array $uuids
* @return HttpSocketResponseExtended
* @throws HttpSocketJsonException
* @throws HttpSocketHttpException
*/
public function fetchAnalystData($type, array $uuids)
{
if (!$this->isSupported(self::PERM_ANALYST_DATA)) {
return [];
throw new RuntimeException("Remote server do not support analyst data");
}
$params = [
@ -264,12 +267,10 @@ class ServerSyncTool
$url .= $this->createParams($params);
$url .= '.json';
return $this->get($url);
// $response = $this->post('/analyst_data/restSearch' , $params);
// return $response->json();
}
/**
/**
* @param string $type
* @param array $analystData
* @return HttpSocketResponseExtended
* @throws HttpSocketHttpException

View File

@ -1007,9 +1007,14 @@ class AnalystData extends AppModel
*
* @param array $user
* @param ServerSyncTool $serverSync
* @return int Number of saved analysis
*/
public function pull(array $user, ServerSyncTool $serverSync)
{
if (!$serverSync->isSupported(ServerSyncTool::PERM_ANALYST_DATA)) {
return 0;
}
$this->Server = ClassRegistry::init('Server');
$this->AnalystData = ClassRegistry::init('AnalystData');
try {
@ -1051,14 +1056,11 @@ class AnalystData extends AppModel
return 0;
}
if ($serverSync->isSupported(ServerSyncTool::PERM_ANALYST_DATA)) {
return $this->pullInChunks($user, $remoteUUIDsToFetch, $serverSync);
}
return $this->pullInChunks($user, $remoteUUIDsToFetch, $serverSync);
}
public function pullInChunks(array $user, array $analystDataUuids, ServerSyncTool $serverSync)
private function pullInChunks(array $user, array $analystDataUuids, ServerSyncTool $serverSync)
{
$uuids = array_keys($analystDataUuids);
$saved = 0;
$serverOrgUUID = $this->Org->find('first', [
'recursive' => -1,

View File

@ -1990,7 +1990,7 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `event_reports` modify `content` mediumtext";
break;
case 117:
$sqlArray[] = "CREATE TABLE `user_login_profiles` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `user_login_profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`user_id` int(11) NOT NULL,
@ -2018,7 +2018,7 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `access_logs` MODIFY `action` varchar(191) NOT NULL";
break;
case 121:
$sqlArray[] = "CREATE TABLE `notes` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `notes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`object_uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
@ -2043,7 +2043,7 @@ class AppModel extends Model
KEY `sharing_group_id` (`sharing_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
$sqlArray[] = "CREATE TABLE `opinions` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `opinions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`object_uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
@ -2069,7 +2069,7 @@ class AppModel extends Model
KEY `opinion` (`opinion`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
$sqlArray[] = "CREATE TABLE `relationships` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `relationships` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) CHARACTER SET ascii NOT NULL,
`object_uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
@ -2117,7 +2117,7 @@ class AppModel extends Model
$sqlArray[] = "ALTER TABLE `servers` ADD `pull_analyst_data` tinyint(1) NOT NULL DEFAULT 0 AFTER `push_analyst_data`;";
break;
case 122:
$sqlArray[] = "CREATE TABLE `collections` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `collections` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`org_id` int(10) unsigned NOT NULL,
@ -2141,7 +2141,7 @@ class AppModel extends Model
KEY `sharing_group_id` (`sharing_group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";
$sqlArray[] = "CREATE TABLE `collection_elements` (
$sqlArray[] = "CREATE TABLE IF NOT EXISTS `collection_elements` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`element_uuid` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,

View File

@ -2257,6 +2257,7 @@ class Event extends AppModel
}
}
$event['Attribute'] = array_values($event['Attribute']);
unset($attribute);
}
if (!empty($event['Object'])) {
if (!$sharingGroupReferenceOnly) {
@ -3465,7 +3466,7 @@ class Event extends AppModel
if ($tagId && !in_array($tagId, $event_tag_ids)) {
$eventTags[] = array(
'tag_id' => $tagId,
'local' => isset($tag['local']) ? $tag['local'] : 0,
'local' => isset($tag['local']) ? $tag['local'] : false,
'relationship_type' => isset($tag['relationship_type']) ? $tag['relationship_type'] : '',
);
$event_tag_ids[] = $tagId;
@ -3481,7 +3482,7 @@ class Event extends AppModel
if ($tag_id && !in_array($tag_id, $event_tag_ids)) {
$eventTags[] = [
'tag_id' => $tag_id,
'local' => isset($tag['local']) ? $tag['local'] : 0,
'local' => isset($tag['local']) ? $tag['local'] : false,
'relationship_type' => isset($tag['relationship_type']) ? $tag['relationship_type'] : '',
];
$event_tag_ids[] = $tag_id;
@ -3559,7 +3560,7 @@ class Event extends AppModel
if ($tagId) {
$attributeTags[] = [
'tag_id' => $tagId,
'local' => isset($tag['local']) ? $tag['local'] : 0,
'local' => isset($tag['local']) ? $tag['local'] : false,
'relationship_type' => isset($tag['relationship_type']) ? $tag['relationship_type'] : '',
];
}
@ -5970,8 +5971,8 @@ class Event extends AppModel
} else {
$event = $this->find('first', array(
'recursive' => -1,
'conditions' => array('Event.id' => $eventOrEventId),
'fields' => ['id', 'info'], // info is required because of SysLogLogableBehavior
'conditions' => array('Event.id' => $eventOrEventId)
//'fields' => ['id', 'info'], // info is required because of SysLogLogableBehavior
));
if (empty($event)) {
return false;
@ -6376,7 +6377,7 @@ class Event extends AppModel
unset($data[$dataType . 'Tag'][$k]);
continue;
}
$dataTag['Tag']['local'] = empty($dataTag['local']) ? 0 : 1;
$dataTag['Tag']['local'] = empty($dataTag['local']) ? false : true;
if (!isset($excludeGalaxy) || !$excludeGalaxy) {
if (substr($dataTag['Tag']['name'], 0, strlen('misp-galaxy:')) === 'misp-galaxy:') {
$cluster = $this->GalaxyCluster->getCluster($dataTag['Tag']['name'], $user);
@ -7322,7 +7323,7 @@ class Event extends AppModel
foreach ($event['EventTag'] as $etk => $eventTag) {
$tag = $this->__getCachedTag($eventTag['tag_id'], $justExportable);
if ($tag !== null) {
$tag['local'] = empty($eventTag['local']) ? 0 : 1;
$tag['local'] = empty($eventTag['local']) ? false : true;
$tag['relationship_type'] = empty($eventTag['relationship_type']) ? null : $eventTag['relationship_type'];
$event['EventTag'][$etk]['Tag'] = $tag;
} else {
@ -7337,7 +7338,7 @@ class Event extends AppModel
foreach ($attribute['AttributeTag'] as $atk => $attributeTag) {
$tag = $this->__getCachedTag($attributeTag['tag_id'], $justExportable);
if ($tag !== null) {
$tag['local'] = empty($attributeTag['local']) ? 0 : 1;
$tag['local'] = empty($attributeTag['local']) ? false : true;
$tag['relationship_type'] = empty($attributeTag['relationship_type']) ? null : $attributeTag['relationship_type'];
$event['Attribute'][$ak]['AttributeTag'][$atk]['Tag'] = $tag;
} else {

View File

@ -38,6 +38,7 @@ class Log extends AppModel
'add',
'admin_email',
'attachTags',
'attachTagToObject',
'auth',
'auth_fail',
'auth_alert',
@ -78,6 +79,7 @@ class Log extends AppModel
'registration',
'registration_error',
'remove_dead_workers',
'removeTagFromObject',
'request',
'request_delegation',
'reset_auth_key',

View File

@ -580,7 +580,17 @@ class Server extends AppModel
}
return false;
}
$this->__checkIfPulledEventExistsAndAddOrUpdate($event, $eventId, $successes, $fails, $eventModel, $serverSync->server(), $user, $jobId, $force, $response);
try {
$this->__checkIfPulledEventExistsAndAddOrUpdate($event, $eventId, $successes, $fails, $eventModel, $serverSync->server(), $user, $jobId, $force, $response);
} catch (Exception $e) {
$title = __('Pulling an event (#%s) from Server #%s has failed. The sync process was not interrupted.', $eventId, $serverSync->server()['id']);
$this->loadLog()->createLogEntry(
$user,
'error',
'Server',
$serverSync->serverId(),
$title, $e->getMessage());
}
return true;
}

View File

@ -17,6 +17,7 @@ App::uses('Oidc', 'OidcAuth.Lib');
* - OidcAuth.unblock (boolean, default: false)
* - OidcAuth.offline_access (boolean, default: false)
* - OidcAuth.check_user_validity (integer, default `0`)
* - OidcAuth.update_user_role (boolean, default: true) - if disabled, manually modified role in MISP admin interface will be not changed from OIDC
*/
class OidcAuthenticate extends BaseAuthenticate
{

View File

@ -101,7 +101,7 @@ class Oidc
$user['org_id'] = $organisationId;
}
if ($user['role_id'] != $roleId) {
if ($user['role_id'] != $roleId && $this->getConfig('update_user_role', true)) {
$this->User->updateField($user, 'role_id', $roleId);
$this->log($mispUsername, "User role changed from {$user['role_id']} to $roleId.");
$user['role_id'] = $roleId;
@ -232,7 +232,7 @@ class Oidc
return false;
}
if ($update && $user['role_id'] != $roleId) {
if ($update && $user['role_id'] != $roleId && $this->getConfig('update_user_role', true)) {
$this->User->updateField($user, 'role_id', $roleId);
$this->log($user['email'], "User role changed from {$user['role_id']} to $roleId.");
}
@ -458,7 +458,7 @@ class Oidc
private function getConfig($config, $default = null)
{
$value = Configure::read("OidcAuth.$config");
if (empty($value)) {
if ($value === null) {
if ($default === null) {
throw new RuntimeException("Config option `OidcAuth.$config` is not set.");
}

View File

@ -214,6 +214,7 @@ if (!$ajax) {
$('#RelationshipRelationshipType').val($('#pickerRelationshipTypeSelect').val());
$(that).popover('hide')
});
$('#genericModal').attr('tabindex', '')
});
}
<?php endif; ?>

View File

@ -29,17 +29,18 @@
"ext-redis": "For working background jobs and feed and warninglist caches",
"ext-zip": "Enabling processing feeds that are ZIP compressed",
"ext-zlib": "Allow gzip compression of HTTP responses",
"ext-brotli": "Allow brotli compression of HTTP responses",
"ext-brotli": "Allow brotli compression of HTTP responses and audit logs",
"ext-zstd": "For better and faster compression when fetching data from remote servers",
"ext-intl": "For handling IDN domain names",
"ext-ssdeep": "For ssdeep hashes correlation",
"ext-bcmath": "For faster validating IBAN numbers",
"ext-rdkafka": "Required for publishing events to Kafka broker",
"ext-apcu": "To cache data in memory instead of file system",
"ext-simdjson": "To decode JSON structures faster",
"ext-curl": "For faster remote requests",
"ext-curl": "For faster fetching data from remote servers and feeds",
"elasticsearch/elasticsearch": "For logging to elasticsearch",
"aws/aws-sdk-php": "To upload samples to S3",
"jakub-onderka/openid-connect-php": "For OIDC authentication",
"jakub-onderka/openid-connect-php": "To enable OIDC authentication",
"supervisorphp/supervisor": "For managing background jobs",
"guzzlehttp/guzzle": "Required for supervisorphp/supervisor XML-RPC requests",
"lstrojny/fxmlrpc": "Required for supervisorphp/supervisor XML-RPC requests",

@ -1 +1 @@
Subproject commit 838f6497660af602c5d7bde93ce34be1783287dd
Subproject commit 2eca8cb04715be2f743bb8b73a83a4fb3a2a1798

@ -1 +1 @@
Subproject commit 3d12addd56d6e5d00cddcc19cb8a788e7f90c46c
Subproject commit 4bf694a8463b7d24bfea00b98e941ddffcb7c7a0

@ -1 +1 @@
Subproject commit 8cd705ba6200bdd42c0b9565e108b7aaf88db6ac
Subproject commit 5f580a3bb5aec4341787719b4ded294c1bd9321a

@ -1 +1 @@
Subproject commit 2765252e7d097703828cd8b3bdd63ba8ba75c63b
Subproject commit 42ecbaf75fbf9c6e130b9d1a66252f51b467ae52

View File

@ -6,7 +6,7 @@ misp-lib-stix2>=3.0.1.1
mixbox>=1.0.5
plyara>=2.1.1
pydeep2>=0.5.1
pymisp==2.4.186
pymisp==2.4.187
python-magic>=0.4.27
pyzmq>=25.1.1
redis>=5.0.1