aws-security-mcp 0.5.2 → 0.5.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/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.5.2";
7
+ var VERSION = "0.5.3";
8
8
 
9
9
  // src/utils/aws-client.ts
10
10
  import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
@@ -2211,7 +2211,6 @@ import {
2211
2211
  DescribeNetworkInterfacesCommand,
2212
2212
  DescribeSecurityGroupsCommand as DescribeSecurityGroupsCommand2
2213
2213
  } from "@aws-sdk/client-ec2";
2214
- var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
2215
2214
  function makeFinding9(opts) {
2216
2215
  const severity = severityFromScore(opts.riskScore);
2217
2216
  return { ...opts, severity, priority: priorityFromSeverity(severity) };
@@ -6680,9 +6679,8 @@ var MLPS3_CHECK_MAPPING = [
6680
6679
  },
6681
6680
  {
6682
6681
  id: "L3-SMC1-09",
6683
- type: "auto",
6684
- modules: ["service_detection"],
6685
- findingPatterns: ["CloudWatch"]
6682
+ type: "manual",
6683
+ guidance: "\u9700\u914D\u7F6E CloudWatch \u96C6\u4E2D\u76D1\u63A7\u5E73\u53F0\uFF0C\u7ED3\u5408 SNS \u8FDB\u884C\u544A\u8B66\u901A\u77E5"
6686
6684
  },
6687
6685
  {
6688
6686
  id: "L3-SMC1-10",
@@ -6776,226 +6774,57 @@ function evaluateAllFullChecks(scanResults) {
6776
6774
  return evaluateFullCheck(item, mapping, allFindings, scanModules);
6777
6775
  });
6778
6776
  }
6779
- var MLPS_CHECKS = [
6780
- // 一、身份鉴别
6781
- {
6782
- id: "8.1.4.1a",
6783
- category: "\u8EAB\u4EFD\u9274\u522B",
6784
- name: "\u5BC6\u7801\u7B56\u7565",
6785
- modules: ["security_hub_findings"],
6786
- findingPatterns: ["password policy", "password length", "complexity", "password expiry", "reuse prevention", "IAM.7", "IAM.10"]
6787
- },
6788
- {
6789
- id: "8.1.4.1a",
6790
- category: "\u8EAB\u4EFD\u9274\u522B",
6791
- name: "\u5BC6\u94A5\u8F6E\u6362",
6792
- modules: ["security_hub_findings"],
6793
- findingPatterns: ["access key older", "access key rotated", "IAM.3", "IAM.4"]
6794
- },
6795
- {
6796
- id: "8.1.4.1d",
6797
- category: "\u8EAB\u4EFD\u9274\u522B",
6798
- name: "\u53CC\u56E0\u7D20\u8BA4\u8BC1",
6799
- modules: ["security_hub_findings"],
6800
- findingPatterns: ["MFA", "IAM.5", "IAM.6"]
6801
- },
6802
- // 二、访问控制
6803
- {
6804
- id: "8.1.4.2c",
6805
- category: "\u8BBF\u95EE\u63A7\u5236",
6806
- name: "\u6700\u5C0F\u6743\u9650",
6807
- modules: ["iam_privilege_escalation", "security_hub_findings"],
6808
- findingPatterns: [
6809
- "AdministratorAccess",
6810
- "PowerUserAccess",
6811
- "IAMFullAccess",
6812
- "over-permissive",
6813
- "privilege escalation",
6814
- "self-grant",
6815
- "iam:*",
6816
- "create admin",
6817
- "Lambda role passing",
6818
- "CreateAccessKey",
6819
- "AssumeRole"
6820
- ]
6821
- },
6822
- {
6823
- id: "8.1.4.2",
6824
- category: "\u8BBF\u95EE\u63A7\u5236",
6825
- name: "\u5B89\u5168\u7EC4",
6826
- modules: ["network_reachability", "security_hub_findings"],
6827
- findingPatterns: ["allows all ports", "allows SSH", "allows RDP", "MySQL", "PostgreSQL", "MongoDB", "Redis", "high-risk port", "security group", "EC2.18", "EC2.19"]
6828
- },
6829
- // 三、安全审计
6830
- {
6831
- id: "8.1.4.3a",
6832
- category: "\u5B89\u5168\u5BA1\u8BA1",
6833
- name: "\u5BA1\u8BA1\u529F\u80FD",
6834
- modules: ["security_hub_findings"],
6835
- findingPatterns: ["CloudTrail", "not enabled", "multi-region", "not logging", "CloudTrail.1"]
6836
- },
6837
- {
6838
- id: "8.1.4.3b",
6839
- category: "\u5B89\u5168\u5BA1\u8BA1",
6840
- name: "\u5BA1\u8BA1\u5B8C\u6574\u6027",
6841
- modules: ["security_hub_findings"],
6842
- findingPatterns: ["log file validation", "log integrity", "log validation", "CloudTrail.4", "CloudTrail.5"]
6843
- },
6844
- {
6845
- id: "8.1.4.3c",
6846
- category: "\u5B89\u5168\u5BA1\u8BA1",
6847
- name: "\u5BA1\u8BA1\u4FDD\u62A4",
6848
- modules: ["security_hub_findings"],
6849
- findingPatterns: ["CloudTrail", "S3 bucket", "encryption", "versioning", "Block Public Access", "CloudTrail.6", "CloudTrail.7"]
6850
- },
6851
- // 四、入侵防范
6852
- {
6853
- id: "8.1.4.4a",
6854
- category: "\u5165\u4FB5\u9632\u8303",
6855
- name: "GuardDuty \u5A01\u80C1\u68C0\u6D4B",
6856
- modules: ["service_detection", "guardduty_findings"],
6857
- findingPatterns: ["GuardDuty"]
6858
- },
6859
- {
6860
- id: "8.1.4.4a",
6861
- category: "\u5165\u4FB5\u9632\u8303",
6862
- name: "Inspector \u6F0F\u6D1E\u626B\u63CF",
6863
- modules: ["service_detection", "inspector_findings"],
6864
- findingPatterns: ["Inspector", "CVE-"]
6865
- },
6866
- // 五、数据安全
6867
- {
6868
- id: "8.1.4.5a",
6869
- category: "\u6570\u636E\u5B89\u5168",
6870
- name: "\u4F20\u8F93\u52A0\u5BC6",
6871
- modules: ["ssl_certificate", "security_hub_findings"],
6872
- findingPatterns: ["HTTPS", "TLS", "HTTP listener", "certificate", "ELB.1"]
6873
- },
6874
- {
6875
- id: "8.1.4.5b",
6876
- category: "\u6570\u636E\u5B89\u5168",
6877
- name: "S3 \u5B58\u50A8\u52A0\u5BC6",
6878
- modules: ["security_hub_findings"],
6879
- findingPatterns: ["no default encryption", "not encrypted", "S3.4"]
6880
- },
6881
- {
6882
- id: "8.1.4.5b",
6883
- category: "\u6570\u636E\u5B89\u5168",
6884
- name: "EBS \u9ED8\u8BA4\u52A0\u5BC6",
6885
- modules: ["security_hub_findings"],
6886
- findingPatterns: ["EBS default encryption", "EC2.7"]
6887
- },
6888
- {
6889
- id: "8.1.4.5b",
6890
- category: "\u6570\u636E\u5B89\u5168",
6891
- name: "RDS \u5B58\u50A8\u52A0\u5BC6",
6892
- modules: ["security_hub_findings"],
6893
- findingPatterns: ["storage is not encrypted", "RDS.3"]
6894
- },
6895
- // 六、网络安全
6896
- {
6897
- id: "8.1.3.1a",
6898
- category: "\u7F51\u7EDC\u5B89\u5168",
6899
- name: "\u7F51\u7EDC\u67B6\u6784",
6900
- modules: ["security_hub_findings"],
6901
- findingPatterns: ["default VPC", "EC2.2"]
6902
- },
6903
- {
6904
- id: "8.1.3.2a",
6905
- category: "\u7F51\u7EDC\u5B89\u5168",
6906
- name: "\u8FB9\u754C\u9632\u62A4",
6907
- modules: ["network_reachability", "security_hub_findings"],
6908
- findingPatterns: ["allows all ports", "allows SSH", "allows RDP", "security group", "EC2.18", "EC2.19"]
6909
- }
6910
- ];
6911
- var CATEGORY_ORDER = [
6912
- "\u8EAB\u4EFD\u9274\u522B",
6913
- "\u8BBF\u95EE\u63A7\u5236",
6914
- "\u5B89\u5168\u5BA1\u8BA1",
6915
- "\u5165\u4FB5\u9632\u8303",
6916
- "\u6570\u636E\u5B89\u5168",
6917
- "\u7F51\u7EDC\u5B89\u5168"
6918
- ];
6919
- var CATEGORY_SECTION = {
6920
- "\u8EAB\u4EFD\u9274\u522B": "\u4E00\u3001\u8EAB\u4EFD\u9274\u522B",
6921
- "\u8BBF\u95EE\u63A7\u5236": "\u4E8C\u3001\u8BBF\u95EE\u63A7\u5236",
6922
- "\u5B89\u5168\u5BA1\u8BA1": "\u4E09\u3001\u5B89\u5168\u5BA1\u8BA1",
6923
- "\u5165\u4FB5\u9632\u8303": "\u56DB\u3001\u5165\u4FB5\u9632\u8303",
6924
- "\u6570\u636E\u5B89\u5168": "\u4E94\u3001\u6570\u636E\u5B89\u5168",
6925
- "\u7F51\u7EDC\u5B89\u5168": "\u516D\u3001\u7F51\u7EDC\u5B89\u5168"
6926
- };
6927
- function evaluateCheck(check, allFindings, scanModules) {
6928
- const allModulesPresent = check.modules.every(
6929
- (mod) => scanModules.some((m) => m.module === mod && m.status === "success")
6930
- );
6931
- if (!allModulesPresent) {
6932
- return { check, status: "unknown", relatedFindings: [] };
6933
- }
6934
- const relatedFindings = allFindings.filter((f) => {
6935
- const moduleMatch = check.modules.some((mod) => f.module === mod);
6936
- if (!moduleMatch) return false;
6937
- const text = `${f.title} ${f.description}`.toLowerCase();
6938
- return check.findingPatterns.some(
6939
- (pattern) => text.includes(pattern.toLowerCase())
6940
- );
6941
- });
6942
- return {
6943
- check,
6944
- status: relatedFindings.length === 0 ? "clean" : "issues",
6945
- relatedFindings
6946
- };
6947
- }
6948
6777
  function generateMlps3Report(scanResults) {
6949
6778
  const { accountId, region, scanStart } = scanResults;
6950
6779
  const scanTime = scanStart.replace("T", " ").replace(/\.\d+Z$/, " UTC");
6951
- const allFindings = scanResults.modules.flatMap(
6952
- (m) => m.findings.map((f) => ({ ...f, module: f.module ?? m.module }))
6953
- );
6954
- const scanModules = scanResults.modules.map((m) => ({
6955
- module: m.module,
6956
- status: m.status
6957
- }));
6958
- const results = MLPS_CHECKS.map(
6959
- (check) => evaluateCheck(check, allFindings, scanModules)
6960
- );
6961
- const cleanCount = results.filter((r) => r.status === "clean").length;
6962
- const issuesCount = results.filter((r) => r.status === "issues").length;
6963
- const unknownCount = results.filter((r) => r.status === "unknown").length;
6964
- const checkedTotal = cleanCount + issuesCount;
6965
- const total = results.length;
6780
+ const results = evaluateAllFullChecks(scanResults);
6781
+ const autoResults = results.filter((r) => r.mapping.type === "auto");
6782
+ const autoClean = autoResults.filter((r) => r.status === "clean").length;
6783
+ const autoIssues = autoResults.filter((r) => r.status === "issues").length;
6784
+ const autoUnknown = autoResults.filter((r) => r.status === "unknown").length;
6785
+ const checkedTotal = autoClean + autoIssues;
6786
+ const cloudCount = results.filter((r) => r.status === "cloud_provider").length;
6787
+ const manualCount = results.filter((r) => r.status === "manual").length;
6788
+ const naCount = results.filter((r) => r.status === "not_applicable").length;
6966
6789
  const lines = [];
6967
6790
  lines.push("# \u7B49\u4FDD\u4E09\u7EA7\u9884\u68C0\u62A5\u544A");
6968
6791
  lines.push("> **\u672C\u62A5\u544A\u4E3A\u7B49\u4FDD\u4E09\u7EA7\u9884\u68C0\u53C2\u8003\uFF0C\u63D0\u4F9B\u4E91\u5E73\u53F0\u914D\u7F6E\u68C0\u67E5\u6570\u636E\u4E0E\u5EFA\u8BAE\u3002\u5408\u89C4\u5224\u5B9A\uFF08\u7B26\u5408/\u90E8\u5206\u7B26\u5408/\u4E0D\u7B26\u5408\uFF09\u9700\u7531\u6301\u8BC1\u6D4B\u8BC4\u673A\u6784\u6839\u636E\u5B9E\u9645\u60C5\u51B5\u786E\u8BA4\u3002**");
6792
+ lines.push("> **\uFF08GB/T 22239-2019 \u5B8C\u6574\u68C0\u67E5\u6E05\u5355 184 \u9879\uFF09**");
6969
6793
  lines.push("");
6970
6794
  lines.push("## \u8D26\u6237\u4FE1\u606F");
6971
6795
  lines.push(`- Account: ${accountId} | Region: ${region} | \u626B\u63CF\u65F6\u95F4: ${scanTime}`);
6972
6796
  lines.push("");
6973
6797
  lines.push("## \u9884\u68C0\u603B\u89C8");
6974
- lines.push(`- \u5DF2\u68C0\u67E5 ${checkedTotal} \u9879 / \u5171 ${total} \u9879`);
6975
- lines.push(` - \u672A\u53D1\u73B0\u95EE\u9898: ${cleanCount} \u9879`);
6976
- lines.push(` - \u53D1\u73B0\u95EE\u9898: ${issuesCount} \u9879`);
6977
- if (unknownCount > 0) {
6978
- lines.push(` - \u672A\u68C0\u67E5: ${unknownCount} \u9879`);
6798
+ lines.push(`- \u5DF2\u68C0\u67E5: ${checkedTotal} \u9879\uFF08\u672A\u53D1\u73B0\u95EE\u9898: ${autoClean} \u9879 | \u53D1\u73B0\u95EE\u9898: ${autoIssues} \u9879\uFF09`);
6799
+ if (autoUnknown > 0) {
6800
+ lines.push(`- \u672A\u68C0\u67E5: ${autoUnknown} \u9879\uFF08\u5BF9\u5E94\u626B\u63CF\u6A21\u5757\u672A\u8FD0\u884C\uFF09`);
6801
+ }
6802
+ lines.push(`- \u4E91\u5E73\u53F0\u8D1F\u8D23: ${cloudCount} \u9879`);
6803
+ lines.push(`- \u9700\u4EBA\u5DE5\u8BC4\u4F30: ${manualCount} \u9879`);
6804
+ if (naCount > 0) {
6805
+ lines.push(`- \u4E0D\u9002\u7528: ${naCount} \u9879`);
6979
6806
  }
6980
6807
  lines.push("");
6981
- for (const category of CATEGORY_ORDER) {
6982
- const sectionTitle = CATEGORY_SECTION[category];
6983
- const categoryResults = results.filter((r) => r.check.category === category);
6984
- if (categoryResults.length === 0) continue;
6808
+ for (const category of MLPS3_CATEGORY_ORDER) {
6809
+ const sectionTitle = MLPS3_CATEGORY_SECTION[category];
6810
+ const catResults = results.filter(
6811
+ (r) => r.item.categoryCn === category && r.status !== "not_applicable"
6812
+ );
6813
+ if (catResults.length === 0) continue;
6985
6814
  lines.push(`## ${sectionTitle}`);
6986
6815
  lines.push("");
6987
- const byId = /* @__PURE__ */ new Map();
6988
- for (const r of categoryResults) {
6989
- const existing = byId.get(r.check.id) ?? [];
6990
- existing.push(r);
6991
- byId.set(r.check.id, existing);
6816
+ const controlMap = /* @__PURE__ */ new Map();
6817
+ for (const r of catResults) {
6818
+ const key = r.item.controlCn;
6819
+ if (!controlMap.has(key)) controlMap.set(key, []);
6820
+ controlMap.get(key).push(r);
6992
6821
  }
6993
- for (const [checkId, checkResults] of byId) {
6994
- lines.push(`### ${checkId} ${checkResults[0].check.name}`);
6995
- for (const r of checkResults) {
6996
- const icon = r.status === "clean" ? "\u2705" : r.status === "issues" ? "\u274C" : "\u26A0\uFE0F";
6997
- const label = r.status === "unknown" ? " \u672A\u68C0\u67E5" : r.status === "clean" ? " \u672A\u53D1\u73B0\u95EE\u9898" : r.status === "issues" ? " \u53D1\u73B0\u95EE\u9898" : "";
6998
- lines.push(`- [${icon}] ${r.check.name}${label}`);
6822
+ for (const [controlName, controlResults] of controlMap) {
6823
+ lines.push(`### ${controlName}`);
6824
+ for (const r of controlResults) {
6825
+ const icon = r.status === "clean" ? "\u2705" : r.status === "issues" ? "\u274C" : r.status === "unknown" ? "\u26A0\uFE0F" : r.status === "manual" ? "\u{1F4CB}" : "\u{1F3E2}";
6826
+ const suffix = r.status === "unknown" ? " \u2014 \u672A\u68C0\u67E5" : r.status === "manual" ? ` \u2014 ${r.mapping.guidance ?? "\u9700\u4EBA\u5DE5\u8BC4\u4F30"}` : r.status === "cloud_provider" ? ` \u2014 ${r.mapping.note ?? "\u4E91\u5E73\u53F0\u8D1F\u8D23"}` : r.status === "clean" ? " \u672A\u53D1\u73B0\u95EE\u9898" : " \u53D1\u73B0\u95EE\u9898";
6827
+ lines.push(`- [${icon}] ${r.item.id} ${r.item.requirementCn.slice(0, 60)}${r.item.requirementCn.length > 60 ? "\u2026" : ""}${suffix}`);
6999
6828
  if (r.status === "issues" && r.relatedFindings.length > 0) {
7000
6829
  for (const f of r.relatedFindings.slice(0, 3)) {
7001
6830
  lines.push(` - ${f.severity}: ${f.title}`);
@@ -7032,6 +6861,10 @@ function generateMlps3Report(scanResults) {
7032
6861
  }
7033
6862
  lines.push("");
7034
6863
  }
6864
+ if (naCount > 0) {
6865
+ lines.push(`> \u4E0D\u9002\u7528\u9879: ${naCount} \u9879\uFF08\u7269\u8054\u7F51/\u65E0\u7EBF\u7F51\u7EDC/\u79FB\u52A8\u7EC8\u7AEF/\u5DE5\u63A7\u7CFB\u7EDF/\u53EF\u4FE1\u9A8C\u8BC1\u7B49\uFF09`);
6866
+ lines.push("");
6867
+ }
7035
6868
  return lines.join("\n");
7036
6869
  }
7037
6870