Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => $page_title,
'current_route' => 'xdr',
'full_width' => true,
]);
$alert = $alert ?? [];
$mitre = $mitre ?? [];
$raw = $raw ?? [];
$assets = $assets ?? [];
$canManage = $can_manage ?? false;
$ticketEnabled = $ticket_enabled ?? false;
$view = $this;
$sev = (string)($alert['severity'] ?? 'medium');
$st = (string)($alert['local_status'] ?? 'new');
$sevPill = ['critical'=>'status-pill--danger','high'=>'status-pill--orange','medium'=>'status-pill--warning','low'=>'status-pill--info','info'=>'status-pill--neutral'];
$sevLabel = ['critical'=>'Kritisch','high'=>'Hoch','medium'=>'Mittel','low'=>'Niedrig','info'=>'Info'];
$statusLabel = ['new'=>'Neu','investigating'=>'In Bearbeitung','acknowledged'=>'Quittiert','resolved'=>'Erledigt','dismissed'=>'Verworfen'];
$providerLabel = ['trendmicro' => 'Trend Vision One', 'defender' => 'Microsoft Defender XDR'];
$typeLabel = ['oat' => 'Observed Attack Technique', 'alert' => 'Alarm', 'workbench' => 'Workbench Alert'];
$actionLabel = ['suppress' => 'verworfen', 'assign' => 'einer Person zugewiesen', 'ticket' => 'für ein Ticket vorgemerkt'];
?>
<div class="content-header">
<div>
<h1><?= $this->te('XDR-Warnung') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item"><a href="/xdr">XDR</a></li>
<li class="breadcrumb-item active">#<?= (int)($alert['id'] ?? 0) ?></li>
</ol>
</div>
<div class="content-header-actions">
<a href="/xdr" class="btn btn-default btn-sm"><?= $this->te('« Zur Übersicht') ?></a>
</div>
</div>
<div class="page-body">
<div class="detail-card">
<div class="detail-card-header">
<span class="detail-card-title">
<span class="status-pill <?= $sevPill[$sev] ?? 'status-pill--neutral' ?>"><?= $sevLabel[$sev] ?? $view->e($sev) ?></span>
<?= $view->e($alert['title'] ?? '') ?>
</span>
</div>
<div class="detail-card-body">
<table class="data-table">
<tbody>
<tr><th scope="row" style="width:200px;"><?= $this->te('Anbieter') ?></th><td><?= $view->e($providerLabel[$alert['provider']] ?? ($alert['provider'] ?? '')) ?></td></tr>
<tr><th scope="row"><?= $this->te('Typ') ?></th><td><?= $view->e($typeLabel[$alert['alert_type'] ?? ''] ?? ($alert['alert_type'] ?? '–')) ?></td></tr>
<tr><th scope="row"><?= $this->te('Lokaler Status') ?></th><td><span class="status-pill"><?= $statusLabel[$st] ?? $view->e($st) ?></span></td></tr>
<tr><th scope="row"><?= $this->te('Status beim Anbieter') ?></th><td><?= $view->e($alert['provider_status'] ?? '–') ?></td></tr>
<tr><th scope="row"><?= $this->te('Gerät (Anbieter)') ?></th><td><?= $view->e($alert['endpoint_name'] ?? '–') ?></td></tr>
<tr>
<th scope="row"><?= $this->te('Zugeordnetes Asset') ?></th>
<td>
<?php if (!empty($alert['asset_id'])): ?>
<a href="/inventory/<?= (int)$alert['asset_id'] ?>" class="table-link"><?= $view->e($alert['asset_name'] ?? ('#' . $alert['asset_id'])) ?></a>
<?php else: ?>
<span class="status-pill status-pill--danger"><?= $this->te('Nicht zugeordnet') ?></span>
<?php endif; ?>
</td>
</tr>
<tr><th scope="row"><?= $this->te('IP-Adresse') ?></th><td><?= $view->e($alert['ip_address'] ?? '–') ?></td></tr>
<tr><th scope="row"><?= $this->te('MAC-Adresse') ?></th><td><?= $view->e($alert['mac_address'] ?? '–') ?></td></tr>
<tr><th scope="row"><?= $this->te('Agent-GUID') ?></th><td><code><?= $view->e($alert['agent_guid'] ?? '–') ?></code></td></tr>
<tr><th scope="row"><?= $this->te('Erkannt am') ?></th><td><?= $alert['detected_at'] ? $view->e(date('d.m.Y H:i', strtotime((string)$alert['detected_at']))) : '–' ?></td></tr>
<tr>
<th scope="row"><?= $this->t('MITRE ATT&CK') ?></th>
<td>
<?php if (empty($mitre)): ?>–<?php else: foreach ($mitre as $t): ?>
<span class="badge"><?= $view->e($t) ?></span>
<?php endforeach; endif; ?>
</td>
</tr>
<?php if (!empty($alert['assigned_to'])): ?>
<tr><th scope="row"><?= $this->te('Zuständig') ?></th><td><?= $view->e($alert['assigned_to_name'] ?? ('#' . (int)$alert['assigned_to'])) ?></td></tr>
<?php endif; ?>
<?php if (!empty($alert['auto_action'])): ?>
<tr>
<th scope="row"><?= $this->te('Automatisch behandelt') ?></th>
<td>
<?= $view->e($actionLabel[$alert['auto_action']] ?? (string)$alert['auto_action']) ?>
<?php if (!empty($alert['applied_rule_name'])): ?>
<?= $view->t('durch die Regel „{name}"', ['name' => $view->e((string)$alert['applied_rule_name'])]) ?>
<?php else: ?>
<?= $view->te('durch eine inzwischen gelöschte Regel') ?>
<?php endif; ?>
</td>
</tr>
<?php endif; ?>
<?php if (!empty($alert['ticket_id'])): ?>
<tr><th scope="row"><?= $this->te('Verknüpftes Ticket') ?></th><td><a href="/tickets/<?= (int)$alert['ticket_id'] ?>" class="table-link"><?= $this->te('Ticket #{nummer}', ['nummer' => (int)$alert['ticket_id']]) ?></a></td></tr>
<?php endif; ?>
</tbody>
</table>
<?php if (!empty($alert['description'])): ?>
<h4 style="margin-top:1rem;"><?= $this->te('Beschreibung') ?></h4>
<p><?= nl2br($view->e($alert['description'])) ?></p>
<?php endif; ?>
</div>
</div>
<?php if ($canManage): ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Bearbeitung') ?></span></div>
<div class="detail-card-body">
<div style="display:flex; flex-wrap:wrap; gap:2rem;">
<!-- Status -->
<form method="post" action="/xdr/<?= (int)$alert['id'] ?>/status" style="min-width:240px;">
<input type="hidden" name="_csrf" value="<?= $view->e($view->csrf()) ?>">
<div class="form-group">
<label for="f-8f10-local_status"><?= $this->te('Status setzen') ?></label>
<select id="f-8f10-local_status" name="local_status" class="form-control form-control-sm">
<?php foreach ($statusLabel as $k => $lbl): ?>
<option value="<?= $k ?>" <?= $st === $k ? 'selected' : '' ?>><?= $lbl ?></option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-primary btn-sm"><?= $this->te('Speichern') ?></button>
</form>
<!-- Asset-Zuordnung -->
<form method="post" action="/xdr/<?= (int)$alert['id'] ?>/assign" style="min-width:320px;">
<input type="hidden" name="_csrf" value="<?= $view->e($view->csrf()) ?>">
<div class="form-group">
<label for="f-8f10-asset_id"><?= $this->te('Asset zuordnen') ?></label>
<select id="f-8f10-asset_id" name="asset_id" class="form-control form-control-sm">
<option value="0"><?= $this->te('— nicht zugeordnet —') ?></option>
<?php foreach ($assets as $opt): ?>
<option value="<?= (int)$opt['id'] ?>" <?= (int)($alert['asset_id'] ?? 0) === (int)$opt['id'] ? 'selected' : '' ?>>
<?= $view->e($opt['label']) ?>
</option>
<?php endforeach; ?>
</select>
<small class="form-hint"><?= $this->te('Über die Agent-GUID gilt die Zuordnung für alle Warnungen dieses Geräts.') ?></small>
</div>
<button type="submit" class="btn btn-primary btn-sm"><?= $this->te('Zuordnen') ?></button>
</form>
<!-- Ticket -->
<?php if ($ticketEnabled && empty($alert['ticket_id'])): ?>
<form method="post" action="/xdr/<?= (int)$alert['id'] ?>/ticket" style="min-width:200px;">
<input type="hidden" name="_csrf" value="<?= $view->e($view->csrf()) ?>">
<div class="form-group">
<label><?= $this->te('Incident-Handling') ?></label>
<div><button type="submit" class="btn btn-default btn-sm"><i class="fas fa-ticket-alt"></i> <?= $this->te('Ticket erstellen') ?></button></div>
</div>
</form>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>
<div class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Rohdaten') ?></span></div>
<div class="detail-card-body">
<pre style="max-height:480px; overflow:auto; background:var(--color-bg-alt); border:1px solid var(--color-border); border-radius:.4rem; padding:1rem; font-size:.78rem;"><?= $view->e(json_encode($raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) ?></pre>
</div>
</div>
</div>