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
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var VERSION = "0.
|
|
7
|
+
var VERSION = "0.7.1";
|
|
8
8
|
|
|
9
9
|
// src/utils/aws-client.ts
|
|
10
10
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -1017,7 +1017,7 @@ async function dnsResolves(hostname) {
|
|
|
1017
1017
|
var DnsDanglingScanner = class {
|
|
1018
1018
|
moduleName = "dns_dangling";
|
|
1019
1019
|
async scan(ctx) {
|
|
1020
|
-
const { region, partition
|
|
1020
|
+
const { region, partition } = ctx;
|
|
1021
1021
|
const startMs = Date.now();
|
|
1022
1022
|
const findings = [];
|
|
1023
1023
|
const warnings = [];
|
|
@@ -2639,6 +2639,22 @@ import {
|
|
|
2639
2639
|
SecurityHubClient as SecurityHubClient2,
|
|
2640
2640
|
GetFindingsCommand
|
|
2641
2641
|
} from "@aws-sdk/client-securityhub";
|
|
2642
|
+
|
|
2643
|
+
// src/utils/sh-source.ts
|
|
2644
|
+
function getSecurityHubSource(finding) {
|
|
2645
|
+
const impact = finding.impact ?? "";
|
|
2646
|
+
const match = impact.match(/^Source:\s*([^(]+)/);
|
|
2647
|
+
if (!match) return "Other";
|
|
2648
|
+
const product = match[1].trim();
|
|
2649
|
+
if (product === "Security Hub" || product.includes("Foundational")) return "FSBP";
|
|
2650
|
+
if (product === "Inspector" || product.includes("Inspector")) return "Inspector";
|
|
2651
|
+
if (product === "GuardDuty" || product.includes("GuardDuty")) return "GuardDuty";
|
|
2652
|
+
if (product === "Config" || product.includes("Config")) return "Config";
|
|
2653
|
+
if (product === "IAM Access Analyzer" || product.includes("Access Analyzer")) return "Access Analyzer";
|
|
2654
|
+
return "Other";
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
// src/scanners/security-hub-findings.ts
|
|
2642
2658
|
function shSeverityToScore(label) {
|
|
2643
2659
|
switch (label) {
|
|
2644
2660
|
case "CRITICAL":
|
|
@@ -2708,7 +2724,7 @@ var SecurityHubFindingsScanner = class {
|
|
|
2708
2724
|
if (recText && !["See References", "None Provided", ""].includes(recText.trim())) {
|
|
2709
2725
|
remediationSteps.push(recText);
|
|
2710
2726
|
}
|
|
2711
|
-
|
|
2727
|
+
const finding = {
|
|
2712
2728
|
severity,
|
|
2713
2729
|
title: f.Title ?? "Security Hub Finding",
|
|
2714
2730
|
resourceType,
|
|
@@ -2722,7 +2738,9 @@ var SecurityHubFindingsScanner = class {
|
|
|
2722
2738
|
priority: priorityFromSeverity(severity),
|
|
2723
2739
|
module: this.moduleName,
|
|
2724
2740
|
accountId: f.AwsAccountId ?? accountId
|
|
2725
|
-
}
|
|
2741
|
+
};
|
|
2742
|
+
finding.source = getSecurityHubSource(finding);
|
|
2743
|
+
findings.push(finding);
|
|
2726
2744
|
}
|
|
2727
2745
|
nextToken = resp.NextToken;
|
|
2728
2746
|
} while (nextToken);
|
|
@@ -7016,11 +7034,24 @@ function generateMlps3Report(scanResults, lang) {
|
|
|
7016
7034
|
function esc(s) {
|
|
7017
7035
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
7018
7036
|
}
|
|
7037
|
+
function safeUrl(url) {
|
|
7038
|
+
try {
|
|
7039
|
+
const u = new URL(url);
|
|
7040
|
+
if (u.protocol === "https:" || u.protocol === "http:") return url;
|
|
7041
|
+
return null;
|
|
7042
|
+
} catch {
|
|
7043
|
+
return null;
|
|
7044
|
+
}
|
|
7045
|
+
}
|
|
7019
7046
|
function escWithLinks(s) {
|
|
7020
7047
|
const parts = s.split(/(https?:\/\/\S+)/);
|
|
7021
7048
|
return parts.map((part, i) => {
|
|
7022
7049
|
if (i % 2 === 1) {
|
|
7023
|
-
|
|
7050
|
+
const safe = safeUrl(part);
|
|
7051
|
+
if (safe) {
|
|
7052
|
+
return `<a href="${esc(safe)}" style="color:#60a5fa" target="_blank" rel="noopener">${esc(part)}</a>`;
|
|
7053
|
+
}
|
|
7054
|
+
return esc(part);
|
|
7024
7055
|
}
|
|
7025
7056
|
return esc(part);
|
|
7026
7057
|
}).join("");
|
|
@@ -7046,18 +7077,6 @@ var SEVERITY_ORDER2 = ["CRITICAL", "HIGH", "MEDIUM", "LOW"];
|
|
|
7046
7077
|
function getRecommendationTemplate(rem) {
|
|
7047
7078
|
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}");
|
|
7048
7079
|
}
|
|
7049
|
-
function getSecurityHubSource(finding) {
|
|
7050
|
-
const impact = finding.impact ?? "";
|
|
7051
|
-
const match = impact.match(/^Source:\s*([^(]+)/);
|
|
7052
|
-
if (!match) return "Other";
|
|
7053
|
-
const product = match[1].trim();
|
|
7054
|
-
if (product === "Security Hub" || product.includes("Foundational")) return "FSBP";
|
|
7055
|
-
if (product === "Inspector" || product.includes("Inspector")) return "Inspector";
|
|
7056
|
-
if (product === "GuardDuty" || product.includes("GuardDuty")) return "GuardDuty";
|
|
7057
|
-
if (product === "Config" || product.includes("Config")) return "Config";
|
|
7058
|
-
if (product === "IAM Access Analyzer" || product.includes("Access Analyzer")) return "Access Analyzer";
|
|
7059
|
-
return "Other";
|
|
7060
|
-
}
|
|
7061
7080
|
var SECURITY_HUB_SUB_CAT_ORDER = ["FSBP", "Inspector", "GuardDuty", "Config", "Access Analyzer", "Other"];
|
|
7062
7081
|
function scoreColor(score) {
|
|
7063
7082
|
if (score >= 80) return "#22c55e";
|
|
@@ -7253,6 +7272,7 @@ function sharedCss() {
|
|
|
7253
7272
|
.filter-count{color:#64748b;font-size:13px;margin-left:auto}
|
|
7254
7273
|
@media print{
|
|
7255
7274
|
.filter-toolbar{display:none !important}
|
|
7275
|
+
.finding-card,.module-fold{display:block !important}
|
|
7256
7276
|
body{background:#fff;color:#1e293b;-webkit-print-color-adjust:exact;print-color-adjust:exact}
|
|
7257
7277
|
.container{max-width:100%;padding:20px}
|
|
7258
7278
|
.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}
|
|
@@ -7759,7 +7779,8 @@ ${rest}
|
|
|
7759
7779
|
const renderRec = (r) => {
|
|
7760
7780
|
const sev = r.severity.toLowerCase();
|
|
7761
7781
|
const countLabel = r.count > 1 ? ` (× ${r.count})` : "";
|
|
7762
|
-
const
|
|
7782
|
+
const safeLink = r.url ? safeUrl(r.url) : null;
|
|
7783
|
+
const linkHtml = safeLink ? ` <a href="${esc(safeLink)}" style="color:#60a5fa" target="_blank" rel="noopener">📖</a>` : "";
|
|
7763
7784
|
return `<li><span class="badge badge-${esc(sev)}">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;
|
|
7764
7785
|
};
|
|
7765
7786
|
const TOP_N = 10;
|
|
@@ -7795,7 +7816,8 @@ ${remaining.map(renderRec).join("\n")}
|
|
|
7795
7816
|
document.querySelectorAll('.module-fold').forEach(function(f){
|
|
7796
7817
|
var mod=f.getAttribute('data-module');
|
|
7797
7818
|
if(activeMod!=='ALL'&&mod!==activeMod){f.style.display='none';return;}
|
|
7798
|
-
f.style
|
|
7819
|
+
var hasVisible=f.querySelectorAll('.finding-card:not([style*="display: none"])').length>0;
|
|
7820
|
+
f.style.display=hasVisible?'':'none';
|
|
7799
7821
|
});
|
|
7800
7822
|
document.querySelectorAll('.severity-group-fold').forEach(function(g){
|
|
7801
7823
|
g.style.display=g.querySelectorAll('.finding-card:not([style*="display: none"])').length?'':'none';
|
|
@@ -7917,7 +7939,6 @@ function generateMlps3HtmlReport(scanResults, history, lang) {
|
|
|
7917
7939
|
</section>`;
|
|
7918
7940
|
}
|
|
7919
7941
|
const isEn = (lang ?? "zh") === "en";
|
|
7920
|
-
const itemCat = (r) => isEn ? r.item.categoryEn : r.item.categoryCn;
|
|
7921
7942
|
const itemControl = (r) => isEn ? r.item.controlEn : r.item.controlCn;
|
|
7922
7943
|
const itemReq = (r) => isEn ? r.item.requirementEn : r.item.requirementCn;
|
|
7923
7944
|
const categoryMap = /* @__PURE__ */ new Map();
|
|
@@ -8119,7 +8140,8 @@ ${itemsHtml}
|
|
|
8119
8140
|
const renderMlpsRec = (r) => {
|
|
8120
8141
|
const sev = r.severity.toLowerCase();
|
|
8121
8142
|
const countLabel = r.count > 1 ? ` (× ${r.count})` : "";
|
|
8122
|
-
const
|
|
8143
|
+
const safeLink = r.url ? safeUrl(r.url) : null;
|
|
8144
|
+
const linkHtml = safeLink ? ` <a href="${esc(safeLink)}" style="color:#60a5fa" target="_blank" rel="noopener">📖</a>` : "";
|
|
8123
8145
|
return `<li><span class="badge badge-${esc(sev)}">${esc(r.severity)}</span> ${esc(r.text)}${countLabel}${linkHtml}</li>`;
|
|
8124
8146
|
};
|
|
8125
8147
|
const MLPS_TOP_N = 10;
|