diff --git a/README.md b/README.md index 2a28375fb..b98ff74a8 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,53 @@ MISP - Threat Intelligence Sharing Platform ------------------------------------------- - -![logo](./INSTALL/logos/misp-logo.png?raw=true "MISP") - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Latest ReleaseGitHub version
CI Action
Gitter
Twitter
Localization
Contributors
License
+MISP logo MISP is an open source software solution for collecting, storing, distributing and sharing cyber security indicators and threats about cyber security incidents analysis and malware analysis. MISP is designed by and for incident analysts, security and ICT professionals or malware reversers to support their day-to-day operations to share structured information efficiently. The objective of MISP is to foster the sharing of structured information within the security community and abroad. MISP provides functionalities to support the exchange of information but also the consumption of said information by Network Intrusion Detection Systems (NIDS), LIDS but also log analysis tools, SIEMs. -MISP, Malware Information Sharing Platform and Threat Sharing, core functionalities are: +   ●  Core functions +   ●  Website / Support +   ●  PHP and MISP
+   ●  Installation +   ●  Documentation +   ●  Contributing
+   ●  License + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Latest ReleaseGitHub version
CI
Gitter
Mastodon
Twitter
Localization
Contributors
License
+ +Core functions +------------------ - An **efficient IOC and indicators** database, allowing to store technical and non-technical information about malware samples, incidents, attackers and intelligence. - Automatic **correlation** finding relationships between attributes and indicators from malware, attack campaigns or analysis. The correlation engine includes correlation between attributes and more advanced correlations like Fuzzy hashing correlation (e.g. ssdeep) or CIDR block matching. Correlation can also be enabled or event disabled per attribute. - A **flexible data model** where complex [objects](https://www.misp-project.org/objects.html) can be expressed and **linked together to express threat intelligence, incidents or connected elements**. @@ -73,16 +80,27 @@ A sample event encoded in MISP: Website / Support ------------------ -Checkout the [website](https://www.misp-project.org) for more information about MISP software, standards, tools and communities. +Checkout the [website](https://www.misp-project.org) for more information about MISP software, standards, tools and communities. -Information, news and updates are also regularly posted on the [MISP project twitter account](https://twitter.com/MISPProject) or the [news page](https://www.misp-project.org/news/). +Information, news and updates are also regularly posted on the MISP project [Mastodon account](https://misp-community.org/@misp), [twitter account](https://twitter.com/MISPProject) and [news page](https://www.misp-project.org/news/). + +PHP and MISP +------------- +MISP currently **requires PHP 7.4**, an end-of-life version of PHP. Because of this it is recommended that you only run MISP on distributions or PHP installs that you know will get security fixes backported, like Red Hat or Debian and derratives. + +MISP 3.x, currently in development will support PHP 8.x. + + +Installation +------------- +For test- og production installations we recommend you check out the possible options on [misp-project.org/download](https://www.misp-project.org/download/). Documentation ------------- [MISP user-guide (MISP-book)](https://github.com/MISP/misp-book) is available [online](https://www.circl.lu/doc/misp/) or as [PDF](https://www.circl.lu/doc/misp/book.pdf) or as [EPUB](https://www.circl.lu/doc/misp/book.epub) or as [MOBI/Kindle](https://www.circl.lu/doc/misp/book.mobi). -For the installation guide see the [INSTALL](https://github.com/MISP/MISP/tree/2.4/INSTALL) or [download section](https://www.misp-project.org/download/). +It is also recommended to read the [FAQ](https://github.com/MISP/MISP/wiki/Frequently-Asked-Questions) Contributing ------------ diff --git a/app/Controller/Component/RestResponseComponent.php b/app/Controller/Component/RestResponseComponent.php index 0e3f4d09d..3ae1742cc 100644 --- a/app/Controller/Component/RestResponseComponent.php +++ b/app/Controller/Component/RestResponseComponent.php @@ -323,6 +323,11 @@ class RestResponseComponent extends Component 'description' => 'Simply GET the url endpoint to view the API output of the statistics API. Additional statistics are available via the following tab-options similar to the UI: data, orgs, users, tags, attributehistogram, sightings, attackMatrix', 'params' => array('tab'), 'http_method' => 'GET' + ), + 'totp_delete' => array( + 'description' => 'Simply do a DELETE or POST request to the url', + 'params' => array('user_id'), + 'http_method' => 'DELETE' ) ), 'UserSetting' => array( diff --git a/app/Controller/Component/RestSearchComponent.php b/app/Controller/Component/RestSearchComponent.php index 420fdd82c..82022dd4c 100644 --- a/app/Controller/Component/RestSearchComponent.php +++ b/app/Controller/Component/RestSearchComponent.php @@ -52,6 +52,7 @@ class RestSearchComponent extends Component 'first_seen', 'last_seen', 'eventinfo', + 'sharinggroup', 'allow_proposal_blocking', 'flatten', 'list', diff --git a/app/Controller/GalaxiesController.php b/app/Controller/GalaxiesController.php index 89eb639b6..fdc633d21 100644 --- a/app/Controller/GalaxiesController.php +++ b/app/Controller/GalaxiesController.php @@ -350,14 +350,14 @@ class GalaxiesController extends AppController $items = array( array( 'name' => __('All clusters'), - 'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/0'. '/local:' . $local . '/eventid:' . $eventid + 'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/0'. '/local:' . h($local) . '/eventid:' . h($eventid) ) ); foreach ($galaxies as $galaxy) { if (!isset($galaxy['Galaxy']['kill_chain_order']) || $noGalaxyMatrix) { $items[] = array( 'name' => h($galaxy['Galaxy']['name']), - 'value' => $this->baseurl . "/galaxies/selectCluster/" . $target_id . '/' . $target_type . '/' . $galaxy['Galaxy']['id'] . '/local:' . $local . '/eventid:' . $eventid, + 'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/' . $galaxy['Galaxy']['id'] . '/local:' . h($local) . '/eventid:' . h($eventid), 'template' => array( 'preIcon' => 'fa-' . $galaxy['Galaxy']['icon'], 'name' => $galaxy['Galaxy']['name'], @@ -367,14 +367,14 @@ class GalaxiesController extends AppController } else { // should use matrix instead $param = array( 'name' => $galaxy['Galaxy']['name'], - 'value' => $this->baseurl . "/galaxies/selectCluster/" . $target_id . '/' . $target_type . '/' . $galaxy['Galaxy']['id'] . '/local:' . $local . '/eventid:' . $eventid, + 'value' => $this->baseurl . "/galaxies/selectCluster/" . h($target_id) . '/' . h($target_type) . '/' . $galaxy['Galaxy']['id'] . '/local:' . h($local) . '/eventid:' . h($eventid), 'functionName' => sprintf( "getMatrixPopup('%s', '%s', '%s/local:%s/eventid:%s')", - $target_type, - $target_id, - $galaxy['Galaxy']['id'], - $local, - $eventid + h($target_type), + h($target_id), + h($galaxy['Galaxy']['id']), + h($local), + h($eventid) ), 'isPill' => true, 'isMatrix' => true @@ -405,12 +405,12 @@ class GalaxiesController extends AppController $noGalaxyMatrix = $noGalaxyMatrix ? '1' : '0'; $items = [[ 'name' => __('All namespaces'), - 'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/0' . '/' . $noGalaxyMatrix . '/local:' . $local . '/eventid:' . $eventid + 'value' => $this->baseurl . "/galaxies/selectGalaxy/" . h($target_id) . '/' . h($target_type) . '/0' . '/' . h($noGalaxyMatrix) . '/local:' . h($local) . '/eventid:' . h($eventid) ]]; foreach ($namespaces as $namespace) { $items[] = array( 'name' => $namespace, - 'value' => $this->baseurl . "/galaxies/selectGalaxy/" . $target_id . '/' . $target_type . '/' . $namespace . '/' . $noGalaxyMatrix . '/local:' . $local . '/eventid:' . $eventid + 'value' => $this->baseurl . "/galaxies/selectGalaxy/" . h($target_id) . '/' . h($target_type) . '/' . h($namespace) . '/' . h($noGalaxyMatrix) . '/local:' . h($local) . '/eventid:' . h($eventid) ); } diff --git a/app/Model/Server.php b/app/Model/Server.php index 0a369f81f..8d5d5e78f 100644 --- a/app/Model/Server.php +++ b/app/Model/Server.php @@ -5615,7 +5615,7 @@ class Server extends AppModel ), 'store_api_access_time' => array( 'level' => 1, - 'description' => __('If enabled, MISP will capture the last API access time following a successful authentication using API keys, stored against a user under the last_api_access field.'), + 'description' => __('If enabled, MISP will capture a users\' last API access time following every successful authentication using API keys (as opposed to once max per hour by default). Stored as last_api_access time for the user.'), 'value' => false, 'test' => 'testBool', 'type' => 'boolean', @@ -6407,6 +6407,14 @@ class Server extends AppModel 'type' => 'boolean', 'null' => true ), + 'limit_site_admins_to_host_org' => array( + 'level' => self::SETTING_RECOMMENDED, + 'description' => __('If enabled, it will only be possible to assign site admin roles to users belonging to the instance\'s host org.'), + 'value' => false, + 'test' => 'testBool', + 'type' => 'boolean', + 'null' => true + ), 'disable_browser_cache' => array( 'level' => 0, 'description' => __('If enabled, HTTP headers that block browser cache will be send. Static files (like images or JavaScripts) will still be cached, but not generated pages.'), diff --git a/app/Model/User.php b/app/Model/User.php index afbec075e..3b8318b18 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -262,6 +262,16 @@ class User extends AppModel if (empty($user['nids_sid'])) { $user['nids_sid'] = mt_rand(1000000, 9999999); } + if (!empty(Configure::read('Security.limit_site_admins_to_host_org'))){ + if (!empty($user['role_id']) and !empty($user['org_id'] and $user['org_id'] != Configure::read('MISP.host_org_id'))){ + $role = $this->Role->find('first', array( + 'conditions' => array('Role.id' => $user['role_id']) + )); + if (!empty($role) and $role['Role']['perm_site_admin'] === true){ + $this->invalidate('role_id', "Site admin roles can only be assigned to users of the host org on this instance."); + } + } + } return true; } diff --git a/app/webroot/doc/openapi.yaml b/app/webroot/doc/openapi.yaml index 7e2ff9e9d..aa7187cda 100644 --- a/app/webroot/doc/openapi.yaml +++ b/app/webroot/doc/openapi.yaml @@ -914,6 +914,24 @@ paths: default: $ref: "#/components/responses/ApiErrorResponse" + /users/totp_delete/{userId}: + delete: + summary: "Delete user TOTP" + operationId: deleteUserTotp + tags: + - Users + parameters: + - $ref: "#/components/parameters/userIdParameter" + responses: + "200": + $ref: "#/components/responses/DeleteUserTotpResponse" + "403": + $ref: "#/components/responses/UnauthorizedApiErrorResponse" + "404": + $ref: "#/components/responses/NotFoundUserTotpDeleteResponse" + default: + $ref: "#/components/responses/ApiErrorResponse" + /admin/organisations/add: post: summary: "Add organisation" @@ -5879,6 +5897,23 @@ components: type: string example: "/attributes/1234" + NotFoundUserTotpDeleteError: + type: object + required: + - name + - message + - url + properties: + name: + type: string + example: "Invalid user" + message: + type: string + example: "Invalid user" + url: + type: string + example: "/users/totp_delete/1" + parameters: eventIdParameter: name: eventId @@ -7573,6 +7608,30 @@ components: type: string example: "/admin/users/delete/1" + DeleteUserTotpResponse: + description: "Delete user TOTP response" + content: + application/json: + schema: + type: object + properties: + saved: + type: boolean + success: + type: boolean + name: + type: string + example: "User TOTP deleted." + message: + type: string + example: "User TOTP deleted." + url: + type: string + example: "/users/totp_delete/1" + id: + type: string + example: "1" + OrganisationResponse: description: "Organisation list response" content: @@ -9081,6 +9140,13 @@ components: schema: $ref: "#/components/schemas/NotFoundApiError" + NotFoundUserTotpDeleteResponse: + description: "The specified resource was not found" + content: + application/json: + schema: + $ref: "#/components/schemas/NotFoundUserTotpDeleteError" + UnauthorizedApiErrorResponse: description: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." content: diff --git a/app/webroot/js/restClient.js b/app/webroot/js/restClient.js index f2aecf675..580c8e36a 100644 --- a/app/webroot/js/restClient.js +++ b/app/webroot/js/restClient.js @@ -165,7 +165,11 @@ var debounceTimerUpdate; var previously_selected_template = $('#ServerUrl').data('urlWithoutParam') if (selected_template !== '' && allValidApis[selected_template] !== undefined) { $('#template_description').show(); - $('#ServerMethod').val('POST'); + if(allValidApis[selected_template].http_method !== undefined){ + $('#ServerMethod').val(allValidApis[selected_template].http_method); + } else { + $('#ServerMethod').val('POST'); + } var server_url_changed = $('#ServerUrl').val() != allValidApis[selected_template].url; $('#ServerUrl') .val(allValidApis[selected_template].url)