@dcrays/mobook-security-plugin 2.0.10 → 2.0.12

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/index.js CHANGED
@@ -135,57 +135,64 @@ function verifyLuhn(cardNumber) {
135
135
  const ID_CARD_REGEX = /\b[1-9]\d{5}(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dXx]\b/g;
136
136
  const BANK_CARD_REGEX = /\b[3-6]\d{15,18}\b/g;
137
137
 
138
+ // ---- 脱敏辅助:部分保留 + 星号遮盖 ----
139
+ function maskKeep(str, keepHead, keepTail = 0, minStars = 4) {
140
+ if (str.length <= keepHead + keepTail) return "*".repeat(str.length);
141
+ const stars = Math.max(minStars, str.length - keepHead - keepTail);
142
+ return str.slice(0, keepHead) + "*".repeat(stars) + (keepTail > 0 ? str.slice(-keepTail) : "");
143
+ }
144
+
138
145
  const SENSITIVE_PATTERNS = [
139
146
  {
140
147
  pattern: ID_CARD_REGEX,
141
148
  validator: verifyIdCard,
142
- replacementText: "***身份证号已脱敏***",
149
+ replacer: (m) => maskKeep(m, 3, 4), // 310***********1234
143
150
  name: "身份证号"
144
151
  },
145
152
  {
146
153
  pattern: /\b1[3-9]\d{9}\b/g,
147
- replacement: "***手机号已脱敏***",
154
+ replacer: (m) => maskKeep(m, 3, 4), // 138****5678
148
155
  name: "手机号"
149
156
  },
150
157
  {
151
158
  pattern: BANK_CARD_REGEX,
152
159
  validator: verifyLuhn,
153
- replacementText: "***银行卡号已脱敏***",
160
+ replacer: (m) => maskKeep(m, 4, 4), // 6222***********1234
154
161
  name: "银行卡号"
155
162
  },
156
163
  {
157
- pattern: /\b[a-zA-Z0-9._%+-]+@(qq|163|126|sina|sohu|gmail|outlook|hotmail|yahoo)\.[a-z]{2,}\b/gi,
158
- replacement: "***邮箱已脱敏***",
164
+ pattern: /\b([a-zA-Z0-9._%+-]+)@((?:qq|163|126|sina|sohu|gmail|outlook|hotmail|yahoo)\.[a-z]{2,})\b/gi,
165
+ replacer: (_m, local, domain) => maskKeep(local, 1, 0) + "@" + domain, // j*****@gmail.com
159
166
  name: "个人邮箱"
160
167
  },
161
168
  {
162
169
  pattern: /\b(sk-[a-zA-Z0-9-]{20,})\b/g,
163
- replacement: "***API密钥已脱敏***",
170
+ replacer: (m) => maskKeep(m, 5, 0), // sk-pr**************
164
171
  name: "API Key (sk-)"
165
172
  },
166
173
  {
167
174
  pattern: /\b(AKIA[0-9A-Z]{16})\b/g,
168
- replacement: "***AWS密钥已脱敏***",
175
+ replacer: (m) => maskKeep(m, 4, 0), // AKIA************
169
176
  name: "AWS Access Key"
170
177
  },
171
178
  {
172
179
  pattern: /\b(ghp_[a-zA-Z0-9]{36,})\b/g,
173
- replacement: "***GitHub Token已脱敏***",
180
+ replacer: (m) => maskKeep(m, 4, 0), // ghp_****...
174
181
  name: "GitHub Token"
175
182
  },
176
183
  {
177
184
  pattern: /(password|passwd|pwd|secret_key|secret|token|api_key|apikey|access_key|private_key)\s*[=:]\s*["']?[^\s"',]{6,}/gi,
178
- replacement: "$1=***已脱敏***",
185
+ replacer: (_m, key) => key + "=***", // password=***
179
186
  name: "密码/密钥字段"
180
187
  },
181
188
  {
182
189
  pattern: /\b(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})\b/g,
183
- replacement: "***内网IP已脱敏***",
190
+ replacer: (m) => m.split(".")[0] + ".*.*.*", // 10.*.*.*
184
191
  name: "内网IP"
185
192
  },
186
193
  {
187
194
  pattern: /[^\s"']*\/extensions\/mobook-security-plugin[^\s"']*/g,
188
- replacement: "***插件路径已脱敏***",
195
+ replacer: () => "***插件路径已脱敏***",
189
196
  name: "安全插件路径"
190
197
  },
191
198
  ];
@@ -198,19 +205,21 @@ function sanitizeContent(content) {
198
205
  rule.pattern.lastIndex = 0;
199
206
 
200
207
  if (rule.validator) {
208
+ // 有校验器的规则(身份证、银行卡等)
201
209
  let hasMatch = false;
202
- sanitized = sanitized.replace(rule.pattern, (match) => {
210
+ sanitized = sanitized.replace(rule.pattern, (...args) => {
211
+ const match = args[0];
203
212
  if (rule.validator(match)) {
204
213
  hasMatch = true;
205
- return rule.replacementText;
214
+ return rule.replacer(...args);
206
215
  }
207
216
  return match;
208
217
  });
209
218
  if (hasMatch) matches.push(rule.name);
210
- } else if (rule.replacement) {
219
+ } else if (rule.replacer) {
220
+ // 使用 replacer 函数
211
221
  rule.pattern.lastIndex = 0;
212
- const repl = rule.replacement; // 闭包捕获
213
- const replaced = sanitized.replace(rule.pattern, () => repl);
222
+ const replaced = sanitized.replace(rule.pattern, (...args) => rule.replacer(...args));
214
223
  if (replaced !== sanitized) {
215
224
  matches.push(rule.name);
216
225
  sanitized = replaced;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "mobook-security-plugin",
3
3
  "name": "MoBook 安全防护插件",
4
- "version": "2.0.9",
4
+ "version": "2.0.12",
5
5
  "description": "MoBook 企业级安全插件 - 危险命令分级拦截、敏感信息全渠道脱敏(身份证GB11643/银行卡Luhn校验)、LLM响应拦截、操作审计",
6
6
  "entry": "./index.js",
7
7
  "type": "plugin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/mobook-security-plugin",
3
- "version": "2.0.10",
3
+ "version": "2.0.12",
4
4
  "type": "module",
5
5
  "description": "MoBook 企业级安全插件 - 危险命令分级拦截、敏感信息全渠道脱敏(身份证GB11643/银行卡Luhn校验)、LLM响应拦截、操作审计",
6
6
  "main": "index.js",