aws-security-mcp 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/aws-security-mcp.js +94 -11
- package/dist/bin/aws-security-mcp.js.map +1 -1
- package/dist/src/index.js +94 -11
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -237,7 +237,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
237
237
|
import { z } from "zod";
|
|
238
238
|
|
|
239
239
|
// src/version.ts
|
|
240
|
-
var VERSION = "0.6.
|
|
240
|
+
var VERSION = "0.6.3";
|
|
241
241
|
|
|
242
242
|
// src/utils/aws-client.ts
|
|
243
243
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -3874,6 +3874,12 @@ var zhI18n = {
|
|
|
3874
3874
|
trendTitle: "30\u65E5\u8D8B\u52BF",
|
|
3875
3875
|
findingsBySeverity: "\u6309\u4E25\u91CD\u6027\u5206\u7C7B\u7684\u53D1\u73B0",
|
|
3876
3876
|
showMoreCount: (n) => `\u663E\u793A\u5269\u4F59 ${n} \u9879\u2026`,
|
|
3877
|
+
// Filter toolbar
|
|
3878
|
+
filterSeverity: "\u4E25\u91CD\u6027\uFF1A",
|
|
3879
|
+
filterModule: "\u6A21\u5757\uFF1A",
|
|
3880
|
+
filterAll: "\u5168\u90E8",
|
|
3881
|
+
filterAllModules: "\u5168\u90E8\u6A21\u5757",
|
|
3882
|
+
filterCountTpl: "\u663E\u793A {shown} / {total} \u4E2A\u53D1\u73B0",
|
|
3877
3883
|
// Extended — MLPS extras
|
|
3878
3884
|
// Markdown report
|
|
3879
3885
|
executiveSummary: "\u6267\u884C\u6458\u8981",
|
|
@@ -4144,6 +4150,12 @@ var enI18n = {
|
|
|
4144
4150
|
trendTitle: "30-Day Trends",
|
|
4145
4151
|
findingsBySeverity: "Findings by Severity",
|
|
4146
4152
|
showMoreCount: (n) => `Show ${n} more\u2026`,
|
|
4153
|
+
// Filter toolbar
|
|
4154
|
+
filterSeverity: "Severity:",
|
|
4155
|
+
filterModule: "Module:",
|
|
4156
|
+
filterAll: "All",
|
|
4157
|
+
filterAllModules: "All Modules",
|
|
4158
|
+
filterCountTpl: "Showing {shown} / {total} findings",
|
|
4147
4159
|
// Extended \u2014 MLPS extras
|
|
4148
4160
|
// Markdown report
|
|
4149
4161
|
executiveSummary: "Executive Summary",
|
|
@@ -7459,7 +7471,16 @@ function sharedCss() {
|
|
|
7459
7471
|
.rec-body ol{padding-left:24px}
|
|
7460
7472
|
.rec-body li{margin-bottom:8px;color:#cbd5e1;font-size:13px}
|
|
7461
7473
|
.rec-body .badge{margin-right:6px;vertical-align:middle}
|
|
7474
|
+
.filter-toolbar{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin-bottom:20px;padding:12px 16px;background:#1e293b;border:1px solid #334155;border-radius:8px}
|
|
7475
|
+
.filter-group{display:flex;align-items:center;gap:8px}
|
|
7476
|
+
.filter-label{color:#94a3b8;font-size:13px}
|
|
7477
|
+
.filter-btn{padding:4px 12px;border-radius:4px;border:1px solid #475569;background:transparent;color:#cbd5e1;cursor:pointer;font-size:13px}
|
|
7478
|
+
.filter-btn:hover{background:#334155}
|
|
7479
|
+
.filter-btn.active{background:#3b82f6;border-color:#3b82f6;color:#fff}
|
|
7480
|
+
.filter-select{padding:4px 8px;border-radius:4px;border:1px solid #475569;background:#0f172a;color:#cbd5e1;font-size:13px}
|
|
7481
|
+
.filter-count{color:#64748b;font-size:13px;margin-left:auto}
|
|
7462
7482
|
@media print{
|
|
7483
|
+
.filter-toolbar{display:none !important}
|
|
7463
7484
|
body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
7464
7485
|
.container{max-width:100%;padding:20px}
|
|
7465
7486
|
.card,.score-card,.stat-card,.chart-box,.finding-fold,.top5-card,.trend-chart,.category-fold,.module-fold,.finding-card,.rec-fold{background:#fff;border:1px solid #e2e8f0}
|
|
@@ -7718,13 +7739,14 @@ function generateHtmlReport(scanResults, history, lang) {
|
|
|
7718
7739
|
</section>`;
|
|
7719
7740
|
}
|
|
7720
7741
|
let findingsHtml;
|
|
7742
|
+
let filterToolbarHtml = "";
|
|
7721
7743
|
if (summary.totalFindings === 0) {
|
|
7722
7744
|
findingsHtml = `<div class="no-findings">${esc(t.noIssuesFound)}</div>`;
|
|
7723
7745
|
} else {
|
|
7724
7746
|
const FOLD_THRESHOLD = 20;
|
|
7725
|
-
const renderCard = (f) => {
|
|
7747
|
+
const renderCard = (f, moduleKey) => {
|
|
7726
7748
|
const sev = f.severity.toLowerCase();
|
|
7727
|
-
return `<div class="finding-card sev-${esc(sev)}">
|
|
7749
|
+
return `<div class="finding-card sev-${esc(sev)}" data-severity="${esc(f.severity)}" data-module="${esc(moduleKey)}">
|
|
7728
7750
|
<span class="badge badge-${esc(sev)}">${esc(f.severity)}</span>
|
|
7729
7751
|
<span class="finding-title-text">${esc(f.title)}</span>
|
|
7730
7752
|
<span class="finding-resource">${esc(f.resourceArn || f.resourceId)}</span>
|
|
@@ -7735,12 +7757,12 @@ function generateHtmlReport(scanResults, history, lang) {
|
|
|
7735
7757
|
</div></details>
|
|
7736
7758
|
</div>`;
|
|
7737
7759
|
};
|
|
7738
|
-
const renderCards = (findings) => {
|
|
7760
|
+
const renderCards = (findings, moduleKey) => {
|
|
7739
7761
|
if (findings.length <= FOLD_THRESHOLD) {
|
|
7740
|
-
return findings.map(renderCard).join("\n");
|
|
7762
|
+
return findings.map((f) => renderCard(f, moduleKey)).join("\n");
|
|
7741
7763
|
}
|
|
7742
|
-
const first = findings.slice(0, FOLD_THRESHOLD).map(renderCard).join("\n");
|
|
7743
|
-
const rest = findings.slice(FOLD_THRESHOLD).map(renderCard).join("\n");
|
|
7764
|
+
const first = findings.slice(0, FOLD_THRESHOLD).map((f) => renderCard(f, moduleKey)).join("\n");
|
|
7765
|
+
const rest = findings.slice(FOLD_THRESHOLD).map((f) => renderCard(f, moduleKey)).join("\n");
|
|
7744
7766
|
return `${first}
|
|
7745
7767
|
<details><summary>${t.showRemainingFindings(findings.length - FOLD_THRESHOLD)}</summary>
|
|
7746
7768
|
${rest}
|
|
@@ -7775,7 +7797,7 @@ ${rest}
|
|
|
7775
7797
|
if (aHasCritHigh !== bHasCritHigh) return aHasCritHigh ? -1 : 1;
|
|
7776
7798
|
return b[1].length - a[1].length;
|
|
7777
7799
|
});
|
|
7778
|
-
const renderSeverityGroups = (findings) => {
|
|
7800
|
+
const renderSeverityGroups = (findings, moduleKey) => {
|
|
7779
7801
|
return SEVERITY_ORDER2.map((sev) => {
|
|
7780
7802
|
const sevFindings = findings.filter((f) => f.severity === sev);
|
|
7781
7803
|
if (sevFindings.length === 0) return "";
|
|
@@ -7784,7 +7806,7 @@ ${rest}
|
|
|
7784
7806
|
const label = sev.charAt(0) + sev.slice(1).toLowerCase();
|
|
7785
7807
|
return `<details class="severity-group-fold">
|
|
7786
7808
|
<summary><h4>${emoji} ${label} (${sevFindings.length})</h4></summary>
|
|
7787
|
-
${renderCards(sevFindings)}
|
|
7809
|
+
${renderCards(sevFindings, moduleKey)}
|
|
7788
7810
|
</details>`;
|
|
7789
7811
|
}).filter(Boolean).join("\n");
|
|
7790
7812
|
};
|
|
@@ -7796,16 +7818,38 @@ ${rest}
|
|
|
7796
7818
|
findingsHtml = moduleEntries.map(([modName, modFindings, subCatLabel]) => {
|
|
7797
7819
|
const badges = renderModuleBadges(modFindings);
|
|
7798
7820
|
const displayName = subCatLabel ?? (t.moduleNames[modName] ?? modName);
|
|
7799
|
-
return `<details class="module-fold">
|
|
7821
|
+
return `<details class="module-fold" data-module="${esc(modName)}">
|
|
7800
7822
|
<summary>
|
|
7801
7823
|
<h3>🔒 ${esc(displayName)} (${modFindings.length})</h3>
|
|
7802
7824
|
<span class="module-badges">${badges}</span>
|
|
7803
7825
|
</summary>
|
|
7804
7826
|
<div class="module-body">
|
|
7805
|
-
${renderSeverityGroups(modFindings)}
|
|
7827
|
+
${renderSeverityGroups(modFindings, modName)}
|
|
7806
7828
|
</div>
|
|
7807
7829
|
</details>`;
|
|
7808
7830
|
}).join("\n");
|
|
7831
|
+
const moduleOptions = moduleEntries.map(([modKey, , subCatLabel]) => {
|
|
7832
|
+
const label = subCatLabel ?? (t.moduleNames[modKey] ?? modKey);
|
|
7833
|
+
return `<option value="${esc(modKey)}">${esc(label)}</option>`;
|
|
7834
|
+
}).join("\n ");
|
|
7835
|
+
filterToolbarHtml = `<div class="filter-toolbar" id="filterBar">
|
|
7836
|
+
<div class="filter-group">
|
|
7837
|
+
<span class="filter-label">${esc(t.filterSeverity)}</span>
|
|
7838
|
+
<button class="filter-btn active" data-severity="ALL">${esc(t.filterAll)}</button>
|
|
7839
|
+
<button class="filter-btn" data-severity="CRITICAL">Critical</button>
|
|
7840
|
+
<button class="filter-btn" data-severity="HIGH">High</button>
|
|
7841
|
+
<button class="filter-btn" data-severity="MEDIUM">Medium</button>
|
|
7842
|
+
<button class="filter-btn" data-severity="LOW">Low</button>
|
|
7843
|
+
</div>
|
|
7844
|
+
<div class="filter-group">
|
|
7845
|
+
<span class="filter-label">${esc(t.filterModule)}</span>
|
|
7846
|
+
<select class="filter-select" id="moduleFilter">
|
|
7847
|
+
<option value="ALL">${esc(t.filterAllModules)}</option>
|
|
7848
|
+
${moduleOptions}
|
|
7849
|
+
</select>
|
|
7850
|
+
</div>
|
|
7851
|
+
<div class="filter-count" id="filterCount" data-tpl="${esc(t.filterCountTpl)}"></div>
|
|
7852
|
+
</div>`;
|
|
7809
7853
|
}
|
|
7810
7854
|
let trendHtml = "";
|
|
7811
7855
|
if (history && history.length >= 2) {
|
|
@@ -7961,6 +8005,43 @@ ${remaining.map(renderRec).join("\n")}
|
|
|
7961
8005
|
</div>
|
|
7962
8006
|
</details>`;
|
|
7963
8007
|
}
|
|
8008
|
+
const filterScript = summary.totalFindings > 0 ? `<script>
|
|
8009
|
+
(function(){
|
|
8010
|
+
var activeSev='ALL',activeMod='ALL';
|
|
8011
|
+
var countEl=document.getElementById('filterCount');
|
|
8012
|
+
var tpl=countEl?countEl.getAttribute('data-tpl'):'';
|
|
8013
|
+
function apply(){
|
|
8014
|
+
var cards=document.querySelectorAll('.finding-card[data-severity]');
|
|
8015
|
+
var shown=0,total=cards.length;
|
|
8016
|
+
cards.forEach(function(c){
|
|
8017
|
+
var sevOk=activeSev==='ALL'||c.getAttribute('data-severity')===activeSev;
|
|
8018
|
+
var modOk=activeMod==='ALL'||c.getAttribute('data-module')===activeMod;
|
|
8019
|
+
c.style.display=(sevOk&&modOk)?'':'none';
|
|
8020
|
+
if(sevOk&&modOk)shown++;
|
|
8021
|
+
});
|
|
8022
|
+
if(countEl)countEl.textContent=tpl.replace('{shown}',shown).replace('{total}',total);
|
|
8023
|
+
document.querySelectorAll('.module-fold').forEach(function(f){
|
|
8024
|
+
var mod=f.getAttribute('data-module');
|
|
8025
|
+
if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}
|
|
8026
|
+
f.style.display='';
|
|
8027
|
+
});
|
|
8028
|
+
document.querySelectorAll('.severity-group-fold').forEach(function(g){
|
|
8029
|
+
g.style.display=g.querySelectorAll('.finding-card:not([style*="display: none"])').length?'':'none';
|
|
8030
|
+
});
|
|
8031
|
+
}
|
|
8032
|
+
document.querySelectorAll('.filter-btn[data-severity]').forEach(function(b){
|
|
8033
|
+
b.addEventListener('click',function(){
|
|
8034
|
+
document.querySelectorAll('.filter-btn[data-severity]').forEach(function(x){x.classList.remove('active')});
|
|
8035
|
+
b.classList.add('active');
|
|
8036
|
+
activeSev=b.getAttribute('data-severity');
|
|
8037
|
+
apply();
|
|
8038
|
+
});
|
|
8039
|
+
});
|
|
8040
|
+
var sel=document.getElementById('moduleFilter');
|
|
8041
|
+
if(sel)sel.addEventListener('change',function(){activeMod=sel.value;apply();});
|
|
8042
|
+
apply();
|
|
8043
|
+
})();
|
|
8044
|
+
</script>` : "";
|
|
7964
8045
|
return `<!DOCTYPE html>
|
|
7965
8046
|
<html lang="${htmlLang}">
|
|
7966
8047
|
<head>
|
|
@@ -8017,6 +8098,7 @@ ${buildServiceReminderHtml(modules, lang)}
|
|
|
8017
8098
|
|
|
8018
8099
|
<section>
|
|
8019
8100
|
<h2>${esc(t.allFindings)}</h2>
|
|
8101
|
+
${filterToolbarHtml}
|
|
8020
8102
|
${findingsHtml}
|
|
8021
8103
|
</section>
|
|
8022
8104
|
|
|
@@ -8028,6 +8110,7 @@ ${recsHtml}
|
|
|
8028
8110
|
</footer>
|
|
8029
8111
|
|
|
8030
8112
|
</div>
|
|
8113
|
+
${filterScript}
|
|
8031
8114
|
</body>
|
|
8032
8115
|
</html>`;
|
|
8033
8116
|
}
|