mdefender-pro 1.2.0 → 1.2.2

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.
@@ -0,0 +1,541 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>403 &mdash; Security Action Required | MDefender Pro</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
10
+ <style>
11
+ :root {
12
+ --brand-1: #4f46e5;
13
+ --brand-2: #6366f1;
14
+ --bg-color: #f8fafc;
15
+ --card-bg: #ffffff;
16
+ --text-primary: #0f172a;
17
+ --text-secondary: #475569;
18
+ --text-muted: #94a3b8;
19
+ --border-color: #cbd5e1;
20
+ --font-main: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
21
+ --font-mono: 'JetBrains Mono', Consolas, Monaco, monospace;
22
+ }
23
+ * { margin: 0; padding: 0; box-sizing: border-box; }
24
+ body {
25
+ font-family: var(--font-main);
26
+ background-color: var(--bg-color);
27
+ background-image:
28
+ radial-gradient(circle at 10% 20%, rgba(99, 102, 241, 0.03) 0%, transparent 40%),
29
+ radial-gradient(circle at 90% 80%, rgba(59, 130, 246, 0.03) 0%, transparent 40%);
30
+ color: var(--text-primary);
31
+ min-height: 100vh;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ padding: 20px 14px;
36
+ }
37
+ .container {
38
+ width: 100%;
39
+ max-width: 660px;
40
+ background: var(--card-bg);
41
+ border: 1px solid rgba(226, 232, 240, 0.95);
42
+ border-radius: 12px;
43
+ box-shadow: 0 8px 25px -4px rgba(0, 0, 0, 0.04), 0 4px 6px -2px rgba(0, 0, 0, 0.02);
44
+ padding: 24px 28px;
45
+ text-align: center;
46
+ animation: fadeIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
47
+ }
48
+ @keyframes fadeIn {
49
+ from { opacity: 0; transform: translateY(10px); }
50
+ to { opacity: 1; transform: translateY(0); }
51
+ }
52
+ .logo-wrap {
53
+ margin-bottom: 10px;
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+ justify-content: center;
58
+ }
59
+ .logo-svg {
60
+ width: 48px;
61
+ height: 48px;
62
+ }
63
+ .logo-text {
64
+ font-size: 13.5px;
65
+ font-weight: 800;
66
+ color: #1e293b;
67
+ letter-spacing: 0.5px;
68
+ margin-top: 4px;
69
+ text-transform: uppercase;
70
+ }
71
+ .fw-badge {
72
+ font-size: 9.5px;
73
+ font-weight: 700;
74
+ color: #64748b;
75
+ text-transform: uppercase;
76
+ letter-spacing: 1.5px;
77
+ margin-bottom: 2px;
78
+ }
79
+ .fw-owner {
80
+ font-size: 12px;
81
+ font-weight: 800;
82
+ color: #0f172a;
83
+ text-transform: uppercase;
84
+ letter-spacing: 1px;
85
+ margin-bottom: 12px;
86
+ }
87
+ .main-title {
88
+ font-size: 19px;
89
+ font-weight: 800;
90
+ color: #0f172a;
91
+ letter-spacing: -0.3px;
92
+ margin-bottom: 3px;
93
+ }
94
+ .sub-title {
95
+ font-size: 14px;
96
+ font-weight: 700;
97
+ color: #0f172a;
98
+ margin-bottom: 3px;
99
+ }
100
+ .desc-text {
101
+ font-size: 11.5px;
102
+ color: var(--text-secondary);
103
+ margin-bottom: 12px;
104
+ }
105
+
106
+ .table-container {
107
+ border: 1px solid var(--border-color);
108
+ border-radius: 7px;
109
+ overflow: hidden;
110
+ background: #ffffff;
111
+ margin-bottom: 12px;
112
+ text-align: left;
113
+ }
114
+ .details-table {
115
+ width: 100%;
116
+ border-collapse: collapse;
117
+ }
118
+ .details-table tr {
119
+ border-bottom: 1px solid var(--border-color);
120
+ }
121
+ .details-table tr:last-child {
122
+ border-bottom: none;
123
+ }
124
+ .details-table th {
125
+ background-color: #f8fafc;
126
+ color: #475569;
127
+ font-weight: 700;
128
+ font-size: 11px;
129
+ text-transform: uppercase;
130
+ letter-spacing: 0.4px;
131
+ width: 190px;
132
+ padding: 7px 12px;
133
+ border-right: 1px solid var(--border-color);
134
+ vertical-align: middle;
135
+ }
136
+ .details-table td {
137
+ color: #334155;
138
+ font-weight: 500;
139
+ font-size: 11.5px;
140
+ padding: 7px 12px;
141
+ vertical-align: middle;
142
+ }
143
+
144
+ .threat-row td {
145
+ background-color: #fff5f5 !important;
146
+ color: #991b1b !important;
147
+ }
148
+ .threat-cell-content {
149
+ display: flex;
150
+ align-items: center;
151
+ justify-content: space-between;
152
+ width: 100%;
153
+ gap: 8px;
154
+ }
155
+ .threat-text {
156
+ font-weight: 700;
157
+ color: #dc2626;
158
+ word-break: break-word;
159
+ }
160
+ .info-tag {
161
+ background: #f1f5f9;
162
+ color: #475569;
163
+ border: 1px solid #cbd5e1;
164
+ font-size: 10px;
165
+ font-weight: 600;
166
+ padding: 2px 7px;
167
+ border-radius: 4px;
168
+ text-decoration: none;
169
+ white-space: nowrap;
170
+ }
171
+
172
+ .ip-wrap {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 8px;
176
+ }
177
+ .flag-img {
178
+ border: 1px solid rgba(0, 0, 0, 0.08);
179
+ border-radius: 2px;
180
+ box-shadow: 0 1px 2px rgba(0,0,0,0.05);
181
+ display: inline-block;
182
+ vertical-align: middle;
183
+ }
184
+
185
+ .why-header {
186
+ font-size: 12.5px;
187
+ font-weight: 700;
188
+ color: #0f172a;
189
+ margin-top: 10px;
190
+ margin-bottom: 3px;
191
+ }
192
+ .why-desc {
193
+ font-size: 10.5px;
194
+ color: var(--text-secondary);
195
+ line-height: 1.45;
196
+ max-width: 560px;
197
+ margin: 0 auto 10px;
198
+ }
199
+
200
+ .ref-box {
201
+ background: #f8fafc;
202
+ border: 1px dashed var(--border-color);
203
+ border-radius: 5px;
204
+ padding: 6px 14px;
205
+ font-family: var(--font-mono);
206
+ font-size: 11.5px;
207
+ font-weight: 700;
208
+ color: #0f172a;
209
+ display: inline-block;
210
+ margin-bottom: 12px;
211
+ letter-spacing: 0.5px;
212
+ cursor: pointer;
213
+ transition: all 0.2s ease;
214
+ }
215
+ .ref-box:hover {
216
+ background: #f1f5f9;
217
+ border-color: #94a3b8;
218
+ transform: scale(1.01);
219
+ }
220
+
221
+ .actions {
222
+ display: flex;
223
+ justify-content: center;
224
+ gap: 8px;
225
+ margin-bottom: 8px;
226
+ flex-wrap: wrap;
227
+ }
228
+ .btn {
229
+ display: inline-flex;
230
+ align-items: center;
231
+ justify-content: center;
232
+ padding: 7px 16px;
233
+ border-radius: 6px;
234
+ font-size: 11.5px;
235
+ font-weight: 600;
236
+ text-decoration: none;
237
+ cursor: pointer;
238
+ transition: all 0.2s ease;
239
+ gap: 6px;
240
+ box-shadow: 0 1px 3px rgba(0,0,0,0.02);
241
+ border: none;
242
+ }
243
+ .btn-primary {
244
+ background-color: #1e3a8a;
245
+ color: #ffffff;
246
+ }
247
+ .btn-primary:hover {
248
+ background-color: #172554;
249
+ transform: translateY(-1px);
250
+ box-shadow: 0 3px 5px rgba(0,0,0,0.06);
251
+ color: #ffffff;
252
+ }
253
+ .btn-secondary {
254
+ background-color: #ffffff;
255
+ color: #475569;
256
+ border: 1px solid var(--border-color);
257
+ }
258
+ .btn-secondary:hover {
259
+ background-color: #f8fafc;
260
+ color: #0f172a;
261
+ border-color: #94a3b8;
262
+ transform: translateY(-1px);
263
+ box-shadow: 0 3px 5px rgba(0,0,0,0.04);
264
+ }
265
+
266
+ .footer {
267
+ font-size: 10.5px;
268
+ color: var(--text-muted);
269
+ border-top: 1px solid var(--border-color);
270
+ padding-top: 12px;
271
+ margin-top: 10px;
272
+ }
273
+
274
+ @media (max-width: 768px) {
275
+ .container { padding: 24px; }
276
+ .details-table th, .details-table td {
277
+ display: block;
278
+ width: 100%;
279
+ border-right: none;
280
+ }
281
+ .details-table th {
282
+ background-color: #f8fafc;
283
+ padding-bottom: 6px;
284
+ }
285
+ .details-table td {
286
+ padding-top: 6px;
287
+ border-bottom: none;
288
+ }
289
+ .details-table tr {
290
+ border-bottom: 1px solid var(--border-color);
291
+ display: block;
292
+ }
293
+ .threat-cell-content {
294
+ flex-direction: column;
295
+ align-items: flex-start;
296
+ gap: 8px;
297
+ }
298
+ .actions {
299
+ flex-direction: column;
300
+ width: 100%;
301
+ max-width: 400px;
302
+ margin: 0 auto 12px;
303
+ }
304
+ .btn {
305
+ width: 100%;
306
+ }
307
+ }
308
+ </style>
309
+ </head>
310
+ <body>
311
+ <div class="container">
312
+ <!-- Logo Header -->
313
+ <div class="logo-wrap">
314
+ <svg class="logo-svg" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
315
+ <defs>
316
+ <linearGradient id="shieldBg" x1="0%" y1="0%" x2="100%" y2="100%">
317
+ <stop offset="0%" stop-color="#f8fafc" />
318
+ <stop offset="30%" stop-color="#cbd5e1" />
319
+ <stop offset="70%" stop-color="#94a3b8" />
320
+ <stop offset="100%" stop-color="#475569" />
321
+ </linearGradient>
322
+ <linearGradient id="shieldBorder" x1="0%" y1="0%" x2="100%" y2="0%">
323
+ <stop offset="0%" stop-color="#94a3b8" />
324
+ <stop offset="50%" stop-color="#f1f5f9" />
325
+ <stop offset="100%" stop-color="#475569" />
326
+ </linearGradient>
327
+ <linearGradient id="dragonColor" x1="0%" y1="0%" x2="100%" y2="100%">
328
+ <stop offset="0%" stop-color="#1e293b" />
329
+ <stop offset="100%" stop-color="#0f172a" />
330
+ </linearGradient>
331
+ <filter id="dropShadow" x="-10%" y="-10%" width="120%" height="120%">
332
+ <feDropShadow dx="0" dy="4" stdDeviation="4" flood-color="#0f172a" flood-opacity="0.15" />
333
+ </filter>
334
+ </defs>
335
+ <path d="M60 10 C85 22 98 25 98 48 C98 75 75 98 60 108 C45 98 22 75 22 48 C22 25 35 22 60 10 Z" fill="url(#shieldBg)" stroke="url(#shieldBorder)" stroke-width="3" filter="url(#dropShadow)" />
336
+ <path d="M60 18 C80 28 90 30 90 48 C90 70 70 90 60 98 C50 90 30 70 30 48 C30 30 40 28 60 18 Z" fill="none" stroke="#ffffff" stroke-width="1.5" stroke-opacity="0.8" stroke-dasharray="3 2" />
337
+ <path d="M60 28 C58 35 52 38 48 38 C44 38 43 42 45 44 C47 46 51 44 51 48 C51 52 46 55 42 53 C38 51 36 54 38 58 C40 62 45 60 48 64 C50 66 48 70 44 72 C48 74 54 75 58 72 C58 68 55 65 57 62 C59 59 63 61 65 58 C67 55 66 52 62 50 C64 45 68 46 70 42 C72 38 67 36 65 32 C63 28 61 25 60 28 Z" fill="url(#dragonColor)" />
338
+ </svg>
339
+ <div class="logo-text">MDefender-Pro AI</div>
340
+ </div>
341
+
342
+ <div class="fw-badge">A.S.A.P. Security Firewall</div>
343
+ <div class="fw-owner">Mahabub</div>
344
+
345
+ <h1 class="main-title">403 — SECURITY ACTION REQUIRED</h1>
346
+ <h2 class="sub-title">Access Denied by Corporate WAF</h2>
347
+
348
+ <div class="desc-text" id="desc-msg">Access to [{{SITE_NAME}}] restricted.</div>
349
+
350
+ <!-- Table Section -->
351
+ <div class="table-container">
352
+ <table class="details-table">
353
+ <tr class="threat-row">
354
+ <th>Attack Classification</th>
355
+ <td>
356
+ <div class="threat-cell-content">
357
+ <span class="threat-text">{{ATTACK_TYPE}}</span>
358
+ <span class="info-tag">Detailed info tag</span>
359
+ </div>
360
+ </td>
361
+ </tr>
362
+ <tr>
363
+ <th>Origin Client IP</th>
364
+ <td>
365
+ <div class="ip-wrap">
366
+ <img id="flag-img" src="https://flagcdn.com/w40/bd.png" srcset="https://flagcdn.com/w80/bd.png 2x" width="20" height="15" alt="Flag" class="flag-img" style="display: inline-block;">
367
+ <span><span id="client-ip-display" style="font-family: var(--font-mono); font-weight: 700;">{{CLIENT_IP}}</span><span id="geo-text" style="color: #64748b;"> (GeoIP: Dhaka, Bangladesh)</span></span>
368
+ </div>
369
+ </td>
370
+ </tr>
371
+ <tr>
372
+ <th>Event Timestamp</th>
373
+ <td><span id="utc-time">{{TIMESTAMP}}</span> (Ref: <span id="unix-ref">1788199736</span>)</td>
374
+ </tr>
375
+ <tr>
376
+ <th>Violation Reason</th>
377
+ <td>Request blocked by rule ID: <span id="rule-id-val">96565</span> (Ref: {{ATTACK_TYPE}})</td>
378
+ </tr>
379
+ <tr>
380
+ <th>Protocol Details</th>
381
+ <td>HTTP/1.1 (WAF_VER: 4.1.0)</td>
382
+ </tr>
383
+ <tr>
384
+ <th>Server Host</th>
385
+ <td><span id="server-host">{{SITE_NAME}}</span></td>
386
+ </tr>
387
+ </table>
388
+ </div>
389
+
390
+ <!-- Bottom Explanatory Section -->
391
+ <h3 class="why-header">Why did this happen?</h3>
392
+ <p class="why-desc">
393
+ To maintain system integrity, suspicious requests are automatically analyzed and filtered. If you believe this is a valid corporate action, please share the Reference ID below with your local IT/Security operations. Regular users should clear cache or contact support.
394
+ </p>
395
+
396
+ <div class="ref-box" id="ref-id-box" title="Click to copy Reference ID" onclick="copyRef()">
397
+ REFERENCE ID: {{REFERENCE_ID}}
398
+ </div>
399
+
400
+ <!-- Actions Button Section -->
401
+ <div class="actions">
402
+ <a id="email-link" href="#" class="btn btn-primary">
403
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
404
+ <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
405
+ <polyline points="22,6 12,13 2,6"></polyline>
406
+ </svg>
407
+ Contact Security Operations
408
+ </a>
409
+ <a href="/" class="btn btn-secondary">
410
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
411
+ <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
412
+ <polyline points="9 22 9 12 15 12 15 22"></polyline>
413
+ </svg>
414
+ Return to Homepage
415
+ </a>
416
+ <button type="button" class="btn btn-secondary" onclick="copyRef()">
417
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
418
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
419
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
420
+ </svg>
421
+ Copy Reference ID
422
+ </button>
423
+ </div>
424
+
425
+ <div class="footer">
426
+ Secured by MDefender-Pro AI Firewall. All critical system events are logged and audited.
427
+ </div>
428
+ </div>
429
+
430
+ <script>
431
+ // Fetch GeoIP and real IP details
432
+ const serverDetectedIp = "{{CLIENT_IP}}";
433
+ const ipSpan = document.getElementById('client-ip-display');
434
+ const flagImg = document.getElementById('flag-img');
435
+ const geoText = document.getElementById('geo-text');
436
+
437
+ function updateGeoDisplay(ip, countryCode, city, country) {
438
+ if (ipSpan && ip) {
439
+ ipSpan.innerText = ip;
440
+ }
441
+ if (flagImg && countryCode) {
442
+ const cc = countryCode.toLowerCase();
443
+ flagImg.src = `https://flagcdn.com/w40/${cc}.png`;
444
+ flagImg.srcset = `https://flagcdn.com/w80/${cc}.png 2x`;
445
+ flagImg.alt = countryCode.toUpperCase();
446
+ flagImg.style.display = 'inline-block';
447
+ }
448
+ if (geoText) {
449
+ let geoInfo = '';
450
+ if (city && country) geoInfo = ` (GeoIP: ${city}, ${country})`;
451
+ else if (country) geoInfo = ` (GeoIP: ${country})`;
452
+ geoText.innerText = geoInfo;
453
+ }
454
+ }
455
+
456
+ if (serverDetectedIp && serverDetectedIp !== '127.0.0.1' && serverDetectedIp !== '::1' && serverDetectedIp !== 'localhost' && serverDetectedIp !== 'unknown') {
457
+ // Real public IP forwarded by server
458
+ fetch(`https://ip-api.com/json/${serverDetectedIp}?fields=status,country,city,countryCode,query`)
459
+ .then(r => r.json())
460
+ .then(data => {
461
+ if (data.status === 'success') {
462
+ updateGeoDisplay(data.query || serverDetectedIp, data.countryCode, data.city, data.country);
463
+ }
464
+ }).catch(err => {
465
+ updateGeoDisplay(serverDetectedIp, 'BD', 'Dhaka', 'Bangladesh');
466
+ });
467
+ } else {
468
+ // Local / private IP - discover visitor's public GeoIP from browser client
469
+ fetch('https://ipapi.co/json/')
470
+ .then(r => r.json())
471
+ .then(data => {
472
+ if (data && data.ip) {
473
+ updateGeoDisplay(data.ip, data.country_code, data.city, data.country_name);
474
+ }
475
+ })
476
+ .catch(() => {
477
+ fetch('https://api.country.is')
478
+ .then(r => r.json())
479
+ .then(cData => {
480
+ if (cData && cData.country) {
481
+ updateGeoDisplay(cData.ip || serverDetectedIp, cData.country, '', cData.country);
482
+ }
483
+ })
484
+ .catch(() => {});
485
+ });
486
+ }
487
+
488
+ // Convert Timestamp to UTC format
489
+ const timestampStr = "{{TIMESTAMP}}";
490
+ try {
491
+ const dt = new Date(timestampStr.replace(' ', 'T'));
492
+ if (!isNaN(dt.getTime())) {
493
+ document.getElementById('utc-time').innerText = dt.toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
494
+ document.getElementById('unix-ref').innerText = Math.floor(dt.getTime() / 1000);
495
+ }
496
+ } catch (e) {}
497
+
498
+ // Dynamically compute rule ID from attack type
499
+ const attackType = "{{ATTACK_TYPE}}";
500
+ let hash = 0;
501
+ for (let i = 0; i < attackType.length; i++) {
502
+ hash = attackType.charCodeAt(i) + ((hash << 5) - hash);
503
+ }
504
+ const ruleId = Math.abs(hash % 10000) + 90000;
505
+ const ruleEl = document.getElementById('rule-id-val');
506
+ if (ruleEl) ruleEl.innerText = ruleId;
507
+
508
+ // Server host lookup
509
+ const srvHost = document.getElementById('server-host');
510
+ if (srvHost && (!srvHost.innerText || srvHost.innerText === 'Protected Website' || srvHost.innerText.includes('{{'))) {
511
+ srvHost.innerText = window.location.hostname || "protected.local";
512
+ }
513
+
514
+ // Setup email operations mailto link
515
+ const refId = "{{REFERENCE_ID}}";
516
+ const emailLink = document.getElementById('email-link');
517
+ if (emailLink) {
518
+ emailLink.href = `mailto:security@mdefender-pro.io?subject=WAF Block Reference: ${refId}&body=Hello Security Team,%0D%0A%0D%0AMy request was blocked by the corporate WAF. Details below:%0D%0A- Reference ID: ${refId}%0D%0A- IP: ${clientIp}%0D%0A- Host: ${window.location.host}%0D%0A- Reason: ${attackType}`;
519
+ }
520
+
521
+ function copyRef() {
522
+ navigator.clipboard.writeText(refId).then(() => {
523
+ const refBox = document.getElementById('ref-id-box');
524
+ const originalHtml = refBox.innerHTML;
525
+ refBox.innerHTML = 'COPIED TO CLIPBOARD! ✅';
526
+ refBox.style.color = '#10b981';
527
+ refBox.style.borderColor = '#10b981';
528
+ refBox.style.background = '#ecfdf5';
529
+ setTimeout(() => {
530
+ refBox.innerHTML = originalHtml;
531
+ refBox.style.color = '';
532
+ refBox.style.borderColor = '';
533
+ refBox.style.background = '';
534
+ }, 2000);
535
+ }).catch(err => {
536
+ console.error('Could not copy Reference ID: ', err);
537
+ });
538
+ }
539
+ </script>
540
+ </body>
541
+ </html>