mirror of https://github.com/MISP/MISP
228 lines
8.6 KiB
PHP
228 lines
8.6 KiB
PHP
<?php
|
|
App::uses('AppController', 'Controller');
|
|
|
|
/**
|
|
* @property AccessLog $AccessLog
|
|
*/
|
|
class AccessLogsController extends AppController
|
|
{
|
|
public $components = [
|
|
'RequestHandler',
|
|
];
|
|
|
|
public $paginate = [
|
|
'recursive' => -1,
|
|
'limit' => 60,
|
|
'fields' => ['id', 'created', 'user_id', 'org_id', 'authkey_id', 'ip', 'request_method', 'user_agent', 'request_id', 'controller', 'action', 'url', 'response_code', 'memory_usage', 'duration', 'query_count'],
|
|
'contain' => [
|
|
'User' => ['fields' => ['id', 'email', 'org_id']],
|
|
'Organisation' => ['fields' => ['id', 'name', 'uuid']],
|
|
],
|
|
'order' => [
|
|
'AccessLog.id' => 'DESC'
|
|
],
|
|
];
|
|
|
|
public function admin_index()
|
|
{
|
|
$params = $this->IndexFilter->harvestParameters([
|
|
'created',
|
|
'ip',
|
|
'user',
|
|
'org',
|
|
'request_id',
|
|
'authkey_id',
|
|
'api_request',
|
|
'request_method',
|
|
'controller',
|
|
'action',
|
|
'url',
|
|
'user_agent',
|
|
'memory_usage',
|
|
'duration',
|
|
'query_count',
|
|
'response_code',
|
|
]);
|
|
|
|
$conditions = $this->__searchConditions($params);
|
|
|
|
if ($this->_isRest()) {
|
|
$list = $this->AccessLog->find('all', [
|
|
'conditions' => $conditions,
|
|
'contain' => $this->paginate['contain'],
|
|
]);
|
|
foreach ($list as &$item) {
|
|
if (!empty($item['AccessLog']['request'])) {
|
|
$item['AccessLog']['request'] = base64_encode($item['AccessLog']['request']);
|
|
}
|
|
}
|
|
return $this->RestResponse->viewData($list, 'json');
|
|
}
|
|
if (empty(Configure::read('MISP.log_skip_access_logs_in_application_logs'))) {
|
|
$this->Flash->warning(__('Access logs are logged in both application logs and access logs. Make sure you reconfigure your log monitoring tools and update MISP.log_skip_access_logs_in_application_logs.'));
|
|
}
|
|
|
|
$this->AccessLog->virtualFields['has_query_log'] = 'query_log IS NOT NULL';
|
|
$this->paginate['fields'][] = 'has_query_log';
|
|
$this->paginate['conditions'] = $conditions;
|
|
$list = $this->paginate();
|
|
|
|
$this->set('list', $list);
|
|
$this->set('title_for_layout', __('Access logs'));
|
|
}
|
|
|
|
public function admin_request($id)
|
|
{
|
|
$request = $this->AccessLog->find('first', [
|
|
'conditions' => ['AccessLog.id' => $id],
|
|
'fields' => ['AccessLog.request'],
|
|
]);
|
|
if (empty($request)) {
|
|
throw new NotFoundException(__('Access log not found'));
|
|
}
|
|
|
|
if (empty($request['AccessLog']['request'])) {
|
|
throw new NotFoundException(__('Request body is empty'));
|
|
}
|
|
|
|
$contentType = explode(';', $request['AccessLog']['request_content_type'], 2)[0];
|
|
if ($contentType === 'application/x-www-form-urlencoded' || $contentType === 'multipart/form-data') {
|
|
parse_str($request['AccessLog']['request'], $output);
|
|
// highlight PHP array
|
|
$highlighted = highlight_string("<?php " . var_export($output, true), true);
|
|
$highlighted = trim($highlighted);
|
|
$highlighted = preg_replace("|^\\<code\\>\\<span style\\=\"color\\: #[a-fA-F0-9]{0,6}\"\\>|", "", $highlighted, 1); // remove prefix
|
|
$highlighted = preg_replace("|\\</code\\>\$|", "", $highlighted, 1); // remove suffix 1
|
|
$highlighted = trim($highlighted); // remove line breaks
|
|
$highlighted = preg_replace("|\\</span\\>\$|", "", $highlighted, 1); // remove suffix 2
|
|
$highlighted = trim($highlighted); // remove line breaks
|
|
$highlighted = preg_replace("|^(\\<span style\\=\"color\\: #[a-fA-F0-9]{0,6}\"\\>)(<\\?php )(.*?)(\\</span\\>)|", "\$1\$3\$4", $highlighted); // remove custom added "<?php "
|
|
$data = $highlighted;
|
|
} else {
|
|
$data = h($request['AccessLog']['request']);
|
|
}
|
|
|
|
$this->set('request', $data);
|
|
}
|
|
|
|
public function admin_queryLog($id)
|
|
{
|
|
$request = $this->AccessLog->find('first', [
|
|
'conditions' => ['AccessLog.id' => $id],
|
|
'fields' => ['AccessLog.query_log'],
|
|
]);
|
|
if (empty($request)) {
|
|
throw new NotFoundException(__('Access log not found'));
|
|
}
|
|
|
|
if (empty($request['AccessLog']['query_log'])) {
|
|
throw new NotFoundException(__('Query log is empty'));
|
|
}
|
|
|
|
$this->set('queryLog', $request['AccessLog']['query_log']);
|
|
}
|
|
|
|
/**
|
|
* @param array $params
|
|
* @return array
|
|
*/
|
|
private function __searchConditions(array $params)
|
|
{
|
|
$qbRules = [];
|
|
foreach ($params as $key => $value) {
|
|
if ($key === 'created') {
|
|
$qbRules[] = [
|
|
'id' => $key,
|
|
'operator' => is_array($value) ? 'between' : 'greater_or_equal',
|
|
'value' => $value,
|
|
];
|
|
} else {
|
|
if (is_array($value)) {
|
|
$value = implode('||', $value);
|
|
}
|
|
$qbRules[] = [
|
|
'id' => $key,
|
|
'value' => $value,
|
|
];
|
|
}
|
|
}
|
|
$this->set('qbRules', $qbRules);
|
|
|
|
$conditions = [];
|
|
if (isset($params['user'])) {
|
|
if (is_numeric($params['user'])) {
|
|
$conditions['AccessLog.user_id'] = $params['user'];
|
|
} else {
|
|
$user = $this->User->find('first', [
|
|
'conditions' => ['User.email' => $params['user']],
|
|
'fields' => ['id'],
|
|
]);
|
|
if (!empty($user)) {
|
|
$conditions['AccessLog.user_id'] = $user['User']['id'];
|
|
} else {
|
|
$conditions['AccessLog.user_id'] = -1;
|
|
}
|
|
}
|
|
}
|
|
if (isset($params['ip'])) {
|
|
$conditions['AccessLog.ip'] = inet_pton($params['ip']);
|
|
}
|
|
foreach (['authkey_id', 'request_id', 'controller', 'action'] as $field) {
|
|
if (isset($params[$field])) {
|
|
$conditions['AccessLog.' . $field] = $params[$field];
|
|
}
|
|
}
|
|
if (isset($params['url'])) {
|
|
$conditions['AccessLog.url LIKE'] = "%{$params['url']}%";
|
|
}
|
|
if (isset($params['user_agent'])) {
|
|
$conditions['AccessLog.user_agent LIKE'] = "%{$params['user_agent']}%";
|
|
}
|
|
if (isset($params['memory_usage'])) {
|
|
$conditions['AccessLog.memory_usage >='] = ($params['memory_usage'] * 1024);
|
|
}
|
|
if (isset($params['memory_usage'])) {
|
|
$conditions['AccessLog.memory_usage >='] = ($params['memory_usage'] * 1024);
|
|
}
|
|
if (isset($params['duration'])) {
|
|
$conditions['AccessLog.duration >='] = $params['duration'];
|
|
}
|
|
if (isset($params['query_count'])) {
|
|
$conditions['AccessLog.query_count >='] = $params['query_count'];
|
|
}
|
|
if (isset($params['request_method'])) {
|
|
$methodId = array_flip(AccessLog::REQUEST_TYPES)[$params['request_method']] ?? -1;
|
|
$conditions['AccessLog.request_method'] = $methodId;
|
|
}
|
|
if (isset($params['org'])) {
|
|
if (is_numeric($params['org'])) {
|
|
$conditions['AccessLog.org_id'] = $params['org'];
|
|
} else {
|
|
$org = $this->AccessLog->Organisation->fetchOrg($params['org']);
|
|
if ($org) {
|
|
$conditions['AccessLog.org_id'] = $org['id'];
|
|
} else {
|
|
$conditions['AccessLog.org_id'] = -1;
|
|
}
|
|
}
|
|
}
|
|
if (isset($params['created'])) {
|
|
$tempData = is_array($params['created']) ? $params['created'] : [$params['created']];
|
|
foreach ($tempData as $k => $v) {
|
|
$tempData[$k] = $this->AccessLog->resolveTimeDelta($v);
|
|
}
|
|
if (count($tempData) === 1) {
|
|
$conditions['AccessLog.created >='] = date("Y-m-d H:i:s", $tempData[0]);
|
|
} else {
|
|
if ($tempData[0] < $tempData[1]) {
|
|
$temp = $tempData[1];
|
|
$tempData[1] = $tempData[0];
|
|
$tempData[0] = $temp;
|
|
}
|
|
$conditions['AND'][] = ['AccessLog.created <=' => date("Y-m-d H:i:s", $tempData[0])];
|
|
$conditions['AND'][] = ['AccessLog.created >=' => date("Y-m-d H:i:s", $tempData[1])];
|
|
}
|
|
}
|
|
return $conditions;
|
|
}
|
|
} |