aws-security-mcp 0.6.3 → 0.7.1
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/dashboard/dist/assets/index-AKJ_-GfD.js +46 -0
- package/dashboard/dist/assets/index-UN8P_PO6.css +2 -0
- package/dashboard/dist/data.json +293 -105
- package/dashboard/dist/index.html +2 -2
- package/dist/bin/aws-security-mcp.js +43 -21
- package/dist/bin/aws-security-mcp.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +43 -21
- package/dist/src/index.js.map +1 -1
- package/package.json +2 -2
- package/dashboard/dist/assets/index-BYE-UdjR.js +0 -46
- package/dashboard/dist/assets/index-CQyERuqT.css +0 -2
|
@@ -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.
|
|
240
|
+
var VERSION = "0.7.1";
|
|
241
241
|
|
|
242
242
|
// src/utils/aws-client.ts
|
|
243
243
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -1245,7 +1245,7 @@ async function dnsResolves(hostname) {
|
|
|
1245
1245
|
var DnsDanglingScanner = class {
|
|
1246
1246
|
moduleName = "dns_dangling";
|
|
1247
1247
|
async scan(ctx) {
|
|
1248
|
-
const { region, partition
|
|
1248
|
+
const { region, partition } = ctx;
|
|
1249
1249
|
const startMs = Date.now();
|
|
1250
1250
|
const findings = [];
|
|
1251
1251
|
const warnings = [];
|
|
@@ -2867,6 +2867,22 @@ import {
|
|
|
2867
2867
|
SecurityHubClient as SecurityHubClient2,
|
|
2868
2868
|
GetFindingsCommand
|
|
2869
2869
|
} from "@aws-sdk/client-securityhub";
|
|
2870
|
+
|
|
2871
|
+
// src/utils/sh-source.ts
|
|
2872
|
+
function getSecurityHubSource(finding) {
|
|
2873
|
+
const impact = finding.impact ?? "";
|
|
2874
|
+
const match = impact.match(/^Source:\s*([^(]+)/);
|
|
2875
|
+
if (!match) return "Other";
|
|
2876
|
+
const product = match[1].trim();
|
|
2877
|
+
if (product === "Security Hub" || product.includes("Foundational")) return "FSBP";
|
|
2878
|
+
if (product === "Inspector" || product.includes("Inspector")) return "Inspector";
|
|
2879
|
+
if (product === "GuardDuty" || product.includes("GuardDuty")) return "GuardDuty";
|
|
2880
|
+
if (product === "Config" || product.includes("Config")) return "Config";
|
|
2881
|
+
if (product === "IAM Access Analyzer" || product.includes("Access Analyzer")) return "Access Analyzer";
|
|
2882
|
+
return "Other";
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
// src/scanners/security-hub-findings.ts
|
|
2870
2886
|
function shSeverityToScore(label) {
|
|
2871
2887
|
switch (label) {
|
|
2872
2888
|
case "CRITICAL":
|
|
@@ -2936,7 +2952,7 @@ var SecurityHubFindingsScanner = class {
|
|
|
2936
2952
|
if (recText && !["See References", "None Provided", ""].includes(recText.trim())) {
|
|
2937
2953
|
remediationSteps.push(recText);
|
|
2938
2954
|
}
|
|
2939
|
-
|
|
2955
|
+
const finding = {
|
|
2940
2956
|
severity,
|
|
2941
2957
|
title: f.Title ?? "Security Hub Finding",
|
|
2942
2958
|
resourceType,
|
|
@@ -2950,7 +2966,9 @@ var SecurityHubFindingsScanner = class {
|
|
|
2950
2966
|
priority: priorityFromSeverity(severity),
|
|
2951
2967
|
module: this.moduleName,
|
|
2952
2968
|
accountId: f.AwsAccountId ?? accountId
|
|
2953
|
-
}
|
|
2969
|
+
};
|
|
2970
|
+
finding.source = getSecurityHubSource(finding);
|
|
2971
|
+
findings.push(finding);
|
|
2954
2972
|
}
|
|
2955
2973
|
nextToken = resp.NextToken;
|
|
2956
2974
|
} while (nextToken);
|
|
@@ -7244,11 +7262,24 @@ function generateMlps3Report(scanResults, lang) {
|
|
|
7244
7262
|
function esc(s) {
|
|
7245
7263
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
7246
7264
|
}
|
|
7265
|
+
function safeUrl(url) {
|
|
7266
|
+
try {
|
|
7267
|
+
const u = new URL(url);
|
|
7268
|
+
if (u.protocol === "https:" || u.protocol === "http:") return url;
|
|
7269
|
+
return null;
|
|
7270
|
+
} catch {
|
|
7271
|
+
return null;
|
|
7272
|
+
}
|
|
7273
|
+
}
|
|
7247
7274
|
function escWithLinks(s) {
|
|
7248
7275
|
const parts = s.split(/(https?:\/\/\S+)/);
|
|
7249
7276
|
return parts.map((part, i) => {
|
|
7250
7277
|
if (i % 2 === 1) {
|
|
7251
|
-
|
|
7278
|
+
const safe = safeUrl(part);
|
|
7279
|
+
if (safe) {
|
|
7280
|
+
return `<a href="${esc(safe)}" style="color:#60a5fa" target="_blank" rel="noopener">${esc(part)}</a>`;
|
|
7281
|
+
}
|
|
7282
|
+
return esc(part);
|
|
7252
7283
|
}
|
|
7253
7284
|
return esc(part);
|
|
7254
7285
|
}).join("");
|
|
@@ -7274,18 +7305,6 @@ var SEVERITY_ORDER2 = ["CRITICAL", "HIGH", "MEDIUM", "LOW"];
|
|
|
7274
7305
|
function getRecommendationTemplate(rem) {
|
|
7275
7306
|
return rem.replace(/\b(i-[0-9a-f]+)\b/g, "{instance}").replace(/\b(vol-[0-9a-f]+)\b/g, "{volume}").replace(/\b(sg-[0-9a-f]+)\b/g, "{sg}").replace(/\b(eipalloc-[0-9a-f]+)\b/g, "{eip}").replace(/\b(arn:aws[-\w]*:[^"\s]+)\b/g, "{arn}").replace(/"[^"]+"/g, "{name}").replace(/bucket \S+/g, "bucket {name}").replace(/instance \S+/g, "instance {id}").replace(/volume \S+/g, "volume {id}").replace(/rule \S+/g, "rule {name}");
|
|
7276
7307
|
}
|
|
7277
|
-
function getSecurityHubSource(finding) {
|
|
7278
|
-
const impact = finding.impact ?? "";
|
|
7279
|
-
const match = impact.match(/^Source:\s*([^(]+)/);
|
|
7280
|
-
if (!match) return "Other";
|
|
7281
|
-
const product = match[1].trim();
|
|
7282
|
-
if (product === "Security Hub" || product.includes("Foundational")) return "FSBP";
|
|
7283
|
-
if (product === "Inspector" || product.includes("Inspector")) return "Inspector";
|
|
7284
|
-
if (product === "GuardDuty" || product.includes("GuardDuty")) return "GuardDuty";
|
|
7285
|
-
if (product === "Config" || product.includes("Config")) return "Config";
|
|
7286
|
-
if (product === "IAM Access Analyzer" || product.includes("Access Analyzer")) return "Access Analyzer";
|
|
7287
|
-
return "Other";
|
|
7288
|
-
}
|
|
7289
7308
|
var SECURITY_HUB_SUB_CAT_ORDER = ["FSBP", "Inspector", "GuardDuty", "Config", "Access Analyzer", "Other"];
|
|
7290
7309
|
function scoreColor(score) {
|
|
7291
7310
|
if (score >= 80) return "#22c55e";
|
|
@@ -7481,6 +7500,7 @@ function sharedCss() {
|
|
|
7481
7500
|
.filter-count{color:#64748b;font-size:13px;margin-left:auto}
|
|
7482
7501
|
@media print{
|
|
7483
7502
|
.filter-toolbar{display:none !important}
|
|
7503
|
+
.finding-card,.module-fold{display:block !important}
|
|
7484
7504
|
body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
7485
7505
|
.container{max-width:100%;padding:20px}
|
|
7486
7506
|
.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}
|
|
@@ -7987,7 +8007,8 @@ ${rest}
|
|
|
7987
8007
|
const renderRec = (r) => {
|
|
7988
8008
|
const sev = r.severity.toLowerCase();
|
|
7989
8009
|
const countLabel = r.count > 1 ? ` (× ${r.count})` : "";
|
|
7990
|
-
const
|
|
8010
|
+
const safeLink = r.url ? safeUrl(r.url) : null;
|
|
8011
|
+
const linkHtml = safeLink ? ` <a href="${esc(safeLink)}" style="color:#60a5fa" target="_blank" rel="noopener">📖</a>` : "";
|
|
7991
8012
|
return `<li><span class="badge badge-${esc(sev)}">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;
|
|
7992
8013
|
};
|
|
7993
8014
|
const TOP_N = 10;
|
|
@@ -8023,7 +8044,8 @@ ${remaining.map(renderRec).join("\n")}
|
|
|
8023
8044
|
document.querySelectorAll('.module-fold').forEach(function(f){
|
|
8024
8045
|
var mod=f.getAttribute('data-module');
|
|
8025
8046
|
if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}
|
|
8026
|
-
f.style
|
|
8047
|
+
var hasVisible=f.querySelectorAll('.finding-card:not([style*="display: none"])').length>0;
|
|
8048
|
+
f.style.display=hasVisible?'':'none';
|
|
8027
8049
|
});
|
|
8028
8050
|
document.querySelectorAll('.severity-group-fold').forEach(function(g){
|
|
8029
8051
|
g.style.display=g.querySelectorAll('.finding-card:not([style*="display: none"])').length?'':'none';
|
|
@@ -8145,7 +8167,6 @@ function generateMlps3HtmlReport(scanResults, history, lang) {
|
|
|
8145
8167
|
</section>`;
|
|
8146
8168
|
}
|
|
8147
8169
|
const isEn = (lang ?? "zh") === "en";
|
|
8148
|
-
const itemCat = (r) => isEn ? r.item.categoryEn : r.item.categoryCn;
|
|
8149
8170
|
const itemControl = (r) => isEn ? r.item.controlEn : r.item.controlCn;
|
|
8150
8171
|
const itemReq = (r) => isEn ? r.item.requirementEn : r.item.requirementCn;
|
|
8151
8172
|
const categoryMap = /* @__PURE__ */ new Map();
|
|
@@ -8347,7 +8368,8 @@ ${itemsHtml}
|
|
|
8347
8368
|
const renderMlpsRec = (r) => {
|
|
8348
8369
|
const sev = r.severity.toLowerCase();
|
|
8349
8370
|
const countLabel = r.count > 1 ? ` (× ${r.count})` : "";
|
|
8350
|
-
const
|
|
8371
|
+
const safeLink = r.url ? safeUrl(r.url) : null;
|
|
8372
|
+
const linkHtml = safeLink ? ` <a href="${esc(safeLink)}" style="color:#60a5fa" target="_blank" rel="noopener">📖</a>` : "";
|
|
8351
8373
|
return `<li><span class="badge badge-${esc(sev)}">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;
|
|
8352
8374
|
};
|
|
8353
8375
|
const MLPS_TOP_N = 10;
|