@kenhkl/agent-moss 0.17.10 → 0.17.11

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/cli.js CHANGED
@@ -9918,14 +9918,23 @@ function checkNeverExfilAfterPrivesc(graph) {
9918
9918
  if (candidates.length > 0) {
9919
9919
  const pre = nodes[candidates[candidates.length - 1]];
9920
9920
  const post = nodes[firstEv];
9921
+ const path6 = [
9922
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9923
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9924
+ ];
9921
9925
  return [{
9922
9926
  propertyId: "no-exfil-after-privesc",
9923
9927
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
9924
9928
  riskLevel: "critical",
9925
- path: [
9926
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9927
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9928
- ]
9929
+ path: path6,
9930
+ graph: graphFromPath(nodes, path6, "next", {
9931
+ property_id: "no-exfil-after-privesc",
9932
+ property_short: "P4",
9933
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
9934
+ }, ["privesc", "sink"], true, [
9935
+ { token: "PRIVESC", node_index: 0 },
9936
+ { token: "EXFIL", node_index: 1 }
9937
+ ])
9929
9938
  }];
9930
9939
  }
9931
9940
  return violations;
@@ -9935,14 +9944,23 @@ function checkNeverExfilAfterPrivesc(graph) {
9935
9944
  for (let j = i + 1; j < nodes.length; j++) {
9936
9945
  if (!isExfilNode(nodes[j])) continue;
9937
9946
  if (privescInWindow(nodes, [i], j, windowSec).length === 0) continue;
9947
+ const path6 = [
9948
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9949
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9950
+ ];
9938
9951
  violations.push({
9939
9952
  propertyId: "no-exfil-after-privesc",
9940
9953
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
9941
9954
  riskLevel: "critical",
9942
- path: [
9943
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9944
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9945
- ]
9955
+ path: path6,
9956
+ graph: graphFromPath(nodes, path6, "next", {
9957
+ property_id: "no-exfil-after-privesc",
9958
+ property_short: "P4",
9959
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
9960
+ }, ["privesc", "sink"], true, [
9961
+ { token: "PRIVESC", node_index: 0 },
9962
+ { token: "EXFIL", node_index: 1 }
9963
+ ])
9946
9964
  });
9947
9965
  return violations;
9948
9966
  }
@@ -9967,14 +9985,23 @@ function checkNeverExfilAfterCred(graph) {
9967
9985
  }
9968
9986
  if (pre) {
9969
9987
  const post = nodes[firstEv];
9988
+ const path6 = [
9989
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9990
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9991
+ ];
9970
9992
  return [{
9971
9993
  propertyId: "no-exfil-after-credential",
9972
9994
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
9973
9995
  riskLevel: "critical",
9974
- path: [
9975
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9976
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9977
- ]
9996
+ path: path6,
9997
+ graph: graphFromPath(nodes, path6, "data", {
9998
+ property_id: "no-exfil-after-credential",
9999
+ property_short: "P5",
10000
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
10001
+ }, ["source", "sink"], true, [
10002
+ { token: "CRED", node_index: 0 },
10003
+ { token: "EXFIL", node_index: 1 }
10004
+ ])
9978
10005
  }];
9979
10006
  }
9980
10007
  return violations;
@@ -9983,14 +10010,23 @@ function checkNeverExfilAfterCred(graph) {
9983
10010
  if (!isCredNode(nodes[i])) continue;
9984
10011
  for (let j = i + 1; j < nodes.length; j++) {
9985
10012
  if (isExfilNode(nodes[j])) {
10013
+ const path6 = [
10014
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
10015
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
10016
+ ];
9986
10017
  violations.push({
9987
10018
  propertyId: "no-exfil-after-credential",
9988
10019
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
9989
10020
  riskLevel: "critical",
9990
- path: [
9991
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9992
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9993
- ]
10021
+ path: path6,
10022
+ graph: graphFromPath(nodes, path6, "data", {
10023
+ property_id: "no-exfil-after-credential",
10024
+ property_short: "P5",
10025
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
10026
+ }, ["source", "sink"], true, [
10027
+ { token: "CRED", node_index: 0 },
10028
+ { token: "EXFIL", node_index: 1 }
10029
+ ])
9994
10030
  });
9995
10031
  return violations;
9996
10032
  }
@@ -10142,11 +10178,19 @@ function checkSensitiveDataAggregation(graph) {
10142
10178
  if (!isExfilNode(n)) continue;
10143
10179
  const srcs = sourcesFor(i);
10144
10180
  if (srcs.size >= 2) {
10181
+ const path6 = [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }];
10145
10182
  violations.push({
10146
10183
  propertyId: "sensitive-data-aggregation",
10147
10184
  reason: `\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20\uFF1Aegress \u805A\u5408 ${srcs.size} \u4E2A\u4E8B\u4EF6\u6E90\u6570\u636E\uFF08Rule 12\uFF09`,
10148
10185
  riskLevel: "critical",
10149
- path: [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }]
10186
+ path: path6,
10187
+ graph: graphFromPath(nodes, path6, "next", {
10188
+ property_id: "sensitive-data-aggregation",
10189
+ property_short: "P8",
10190
+ property_name: "\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20"
10191
+ }, ["sink"], true, [
10192
+ { token: "EXFIL", node_index: 0 }
10193
+ ])
10150
10194
  });
10151
10195
  if (witness !== void 0) return violations;
10152
10196
  }
@@ -8836,14 +8836,23 @@ function checkNeverExfilAfterPrivesc(graph) {
8836
8836
  if (candidates.length > 0) {
8837
8837
  const pre = nodes[candidates[candidates.length - 1]];
8838
8838
  const post = nodes[firstEv];
8839
+ const path5 = [
8840
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
8841
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
8842
+ ];
8839
8843
  return [{
8840
8844
  propertyId: "no-exfil-after-privesc",
8841
8845
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
8842
8846
  riskLevel: "critical",
8843
- path: [
8844
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
8845
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
8846
- ]
8847
+ path: path5,
8848
+ graph: graphFromPath(nodes, path5, "next", {
8849
+ property_id: "no-exfil-after-privesc",
8850
+ property_short: "P4",
8851
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
8852
+ }, ["privesc", "sink"], true, [
8853
+ { token: "PRIVESC", node_index: 0 },
8854
+ { token: "EXFIL", node_index: 1 }
8855
+ ])
8847
8856
  }];
8848
8857
  }
8849
8858
  return violations;
@@ -8853,14 +8862,23 @@ function checkNeverExfilAfterPrivesc(graph) {
8853
8862
  for (let j = i + 1; j < nodes.length; j++) {
8854
8863
  if (!isExfilNode(nodes[j])) continue;
8855
8864
  if (privescInWindow(nodes, [i], j, windowSec).length === 0) continue;
8865
+ const path5 = [
8866
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
8867
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
8868
+ ];
8856
8869
  violations.push({
8857
8870
  propertyId: "no-exfil-after-privesc",
8858
8871
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
8859
8872
  riskLevel: "critical",
8860
- path: [
8861
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
8862
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
8863
- ]
8873
+ path: path5,
8874
+ graph: graphFromPath(nodes, path5, "next", {
8875
+ property_id: "no-exfil-after-privesc",
8876
+ property_short: "P4",
8877
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
8878
+ }, ["privesc", "sink"], true, [
8879
+ { token: "PRIVESC", node_index: 0 },
8880
+ { token: "EXFIL", node_index: 1 }
8881
+ ])
8864
8882
  });
8865
8883
  return violations;
8866
8884
  }
@@ -8885,14 +8903,23 @@ function checkNeverExfilAfterCred(graph) {
8885
8903
  }
8886
8904
  if (pre) {
8887
8905
  const post = nodes[firstEv];
8906
+ const path5 = [
8907
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
8908
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
8909
+ ];
8888
8910
  return [{
8889
8911
  propertyId: "no-exfil-after-credential",
8890
8912
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
8891
8913
  riskLevel: "critical",
8892
- path: [
8893
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
8894
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
8895
- ]
8914
+ path: path5,
8915
+ graph: graphFromPath(nodes, path5, "data", {
8916
+ property_id: "no-exfil-after-credential",
8917
+ property_short: "P5",
8918
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
8919
+ }, ["source", "sink"], true, [
8920
+ { token: "CRED", node_index: 0 },
8921
+ { token: "EXFIL", node_index: 1 }
8922
+ ])
8896
8923
  }];
8897
8924
  }
8898
8925
  return violations;
@@ -8901,14 +8928,23 @@ function checkNeverExfilAfterCred(graph) {
8901
8928
  if (!isCredNode(nodes[i])) continue;
8902
8929
  for (let j = i + 1; j < nodes.length; j++) {
8903
8930
  if (isExfilNode(nodes[j])) {
8931
+ const path5 = [
8932
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
8933
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
8934
+ ];
8904
8935
  violations.push({
8905
8936
  propertyId: "no-exfil-after-credential",
8906
8937
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
8907
8938
  riskLevel: "critical",
8908
- path: [
8909
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
8910
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
8911
- ]
8939
+ path: path5,
8940
+ graph: graphFromPath(nodes, path5, "data", {
8941
+ property_id: "no-exfil-after-credential",
8942
+ property_short: "P5",
8943
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
8944
+ }, ["source", "sink"], true, [
8945
+ { token: "CRED", node_index: 0 },
8946
+ { token: "EXFIL", node_index: 1 }
8947
+ ])
8912
8948
  });
8913
8949
  return violations;
8914
8950
  }
@@ -9065,11 +9101,19 @@ function checkSensitiveDataAggregation(graph) {
9065
9101
  if (!isExfilNode(n)) continue;
9066
9102
  const srcs = sourcesFor(i);
9067
9103
  if (srcs.size >= 2) {
9104
+ const path5 = [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }];
9068
9105
  violations.push({
9069
9106
  propertyId: "sensitive-data-aggregation",
9070
9107
  reason: `\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20\uFF1Aegress \u805A\u5408 ${srcs.size} \u4E2A\u4E8B\u4EF6\u6E90\u6570\u636E\uFF08Rule 12\uFF09`,
9071
9108
  riskLevel: "critical",
9072
- path: [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }]
9109
+ path: path5,
9110
+ graph: graphFromPath(nodes, path5, "next", {
9111
+ property_id: "sensitive-data-aggregation",
9112
+ property_short: "P8",
9113
+ property_name: "\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20"
9114
+ }, ["sink"], true, [
9115
+ { token: "EXFIL", node_index: 0 }
9116
+ ])
9073
9117
  });
9074
9118
  if (witness !== void 0) return violations;
9075
9119
  }
package/dist/server.js CHANGED
@@ -9361,14 +9361,23 @@ function checkNeverExfilAfterPrivesc(graph) {
9361
9361
  if (candidates.length > 0) {
9362
9362
  const pre = nodes[candidates[candidates.length - 1]];
9363
9363
  const post = nodes[firstEv];
9364
+ const path6 = [
9365
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9366
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9367
+ ];
9364
9368
  return [{
9365
9369
  propertyId: "no-exfil-after-privesc",
9366
9370
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
9367
9371
  riskLevel: "critical",
9368
- path: [
9369
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9370
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9371
- ]
9372
+ path: path6,
9373
+ graph: graphFromPath(nodes, path6, "next", {
9374
+ property_id: "no-exfil-after-privesc",
9375
+ property_short: "P4",
9376
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
9377
+ }, ["privesc", "sink"], true, [
9378
+ { token: "PRIVESC", node_index: 0 },
9379
+ { token: "EXFIL", node_index: 1 }
9380
+ ])
9372
9381
  }];
9373
9382
  }
9374
9383
  return violations;
@@ -9378,14 +9387,23 @@ function checkNeverExfilAfterPrivesc(graph) {
9378
9387
  for (let j = i + 1; j < nodes.length; j++) {
9379
9388
  if (!isExfilNode(nodes[j])) continue;
9380
9389
  if (privescInWindow(nodes, [i], j, windowSec).length === 0) continue;
9390
+ const path6 = [
9391
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9392
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9393
+ ];
9381
9394
  violations.push({
9382
9395
  propertyId: "no-exfil-after-privesc",
9383
9396
  reason: "\u63D0\u6743\u540E\u51FA\u73B0\u5916\u4F20\uFF1A\u63D0\u6743(\u524D) \u2192 \u5916\u4F20(\u540E)\uFF0C\u8FDD\u53CD \u25A1(PRIVESC\u2192\u25C7EXFIL) \u7A97\u53E3\u7EA6\u675F",
9384
9397
  riskLevel: "critical",
9385
- path: [
9386
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9387
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9388
- ]
9398
+ path: path6,
9399
+ graph: graphFromPath(nodes, path6, "next", {
9400
+ property_id: "no-exfil-after-privesc",
9401
+ property_short: "P4",
9402
+ property_name: "\u63D0\u6743\u540E\u7981\u6B62\u5916\u4F20"
9403
+ }, ["privesc", "sink"], true, [
9404
+ { token: "PRIVESC", node_index: 0 },
9405
+ { token: "EXFIL", node_index: 1 }
9406
+ ])
9389
9407
  });
9390
9408
  return violations;
9391
9409
  }
@@ -9410,14 +9428,23 @@ function checkNeverExfilAfterCred(graph) {
9410
9428
  }
9411
9429
  if (pre) {
9412
9430
  const post = nodes[firstEv];
9431
+ const path6 = [
9432
+ { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9433
+ { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9434
+ ];
9413
9435
  return [{
9414
9436
  propertyId: "no-exfil-after-credential",
9415
9437
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
9416
9438
  riskLevel: "critical",
9417
- path: [
9418
- { sessionId: pre.sessionId, seq: pre.seq, detail: pre.actionDetail.slice(0, 60) },
9419
- { sessionId: post.sessionId, seq: post.seq, detail: post.actionDetail.slice(0, 60) }
9420
- ]
9439
+ path: path6,
9440
+ graph: graphFromPath(nodes, path6, "data", {
9441
+ property_id: "no-exfil-after-credential",
9442
+ property_short: "P5",
9443
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
9444
+ }, ["source", "sink"], true, [
9445
+ { token: "CRED", node_index: 0 },
9446
+ { token: "EXFIL", node_index: 1 }
9447
+ ])
9421
9448
  }];
9422
9449
  }
9423
9450
  return violations;
@@ -9426,14 +9453,23 @@ function checkNeverExfilAfterCred(graph) {
9426
9453
  if (!isCredNode(nodes[i])) continue;
9427
9454
  for (let j = i + 1; j < nodes.length; j++) {
9428
9455
  if (isExfilNode(nodes[j])) {
9456
+ const path6 = [
9457
+ { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9458
+ { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9459
+ ];
9429
9460
  violations.push({
9430
9461
  propertyId: "no-exfil-after-credential",
9431
9462
  reason: "\u8BFB\u53D6\u51ED\u636E\u540E\u51FA\u73B0\u5916\u4F20\uFF0C\u8FDD\u53CD \u25A1(CRED\u2192\xAC\u25C7EXFIL)",
9432
9463
  riskLevel: "critical",
9433
- path: [
9434
- { sessionId: nodes[i].sessionId, seq: nodes[i].seq, detail: nodes[i].actionDetail.slice(0, 60) },
9435
- { sessionId: nodes[j].sessionId, seq: nodes[j].seq, detail: nodes[j].actionDetail.slice(0, 60) }
9436
- ]
9464
+ path: path6,
9465
+ graph: graphFromPath(nodes, path6, "data", {
9466
+ property_id: "no-exfil-after-credential",
9467
+ property_short: "P5",
9468
+ property_name: "\u8BFB\u53D6\u51ED\u636E\u540E\u7981\u6B62\u5916\u4F20"
9469
+ }, ["source", "sink"], true, [
9470
+ { token: "CRED", node_index: 0 },
9471
+ { token: "EXFIL", node_index: 1 }
9472
+ ])
9437
9473
  });
9438
9474
  return violations;
9439
9475
  }
@@ -9585,11 +9621,19 @@ function checkSensitiveDataAggregation(graph) {
9585
9621
  if (!isExfilNode(n)) continue;
9586
9622
  const srcs = sourcesFor(i);
9587
9623
  if (srcs.size >= 2) {
9624
+ const path6 = [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }];
9588
9625
  violations.push({
9589
9626
  propertyId: "sensitive-data-aggregation",
9590
9627
  reason: `\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20\uFF1Aegress \u805A\u5408 ${srcs.size} \u4E2A\u4E8B\u4EF6\u6E90\u6570\u636E\uFF08Rule 12\uFF09`,
9591
9628
  riskLevel: "critical",
9592
- path: [{ sessionId: n.sessionId, seq: n.seq, detail: n.actionDetail.slice(0, 60) }]
9629
+ path: path6,
9630
+ graph: graphFromPath(nodes, path6, "next", {
9631
+ property_id: "sensitive-data-aggregation",
9632
+ property_short: "P8",
9633
+ property_name: "\u654F\u611F\u6570\u636E\u805A\u5408\u5916\u4F20"
9634
+ }, ["sink"], true, [
9635
+ { token: "EXFIL", node_index: 0 }
9636
+ ])
9593
9637
  });
9594
9638
  if (witness !== void 0) return violations;
9595
9639
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenhkl/agent-moss",
3
- "version": "0.17.10",
3
+ "version": "0.17.11",
4
4
  "description": "Multi-layer security analysis engine for AI agents (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",