honeyweb-core 1.0.1 → 1.0.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.
File without changes
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // honeyweb-core/index.js
1
+ // honeyweb-core/index.js (V2 - Full Suite)
2
2
  const fs = require('fs-extra');
3
3
  const path = require('path');
4
4
  const cheerio = require('cheerio');
@@ -7,100 +7,195 @@ const { GoogleGenerativeAI } = require("@google/generative-ai");
7
7
  const DB_FILE = path.join(__dirname, 'blocked-ips.json');
8
8
 
9
9
  // ------------------------------------------------------
10
- // CONFIGURATION
10
+ // 1. CONFIGURATION
11
11
  // ------------------------------------------------------
12
- // ⚠️ PASTE YOUR GOOGLE API KEY HERE
13
- const GOOGLE_API_KEY = 'YOUR_GOOGLE_API_KEY_HERE';
14
-
15
- const TRAP_PATHS = [
16
- '/admin-backup-v2',
17
- '/wp-login-hidden',
18
- '/db-dump-2024',
19
- '/auth/root-access',
20
- '/sys/config-safe'
12
+ const GOOGLE_API_KEY = process.env.HONEYWEB_API_KEY;
13
+
14
+ if (!GOOGLE_API_KEY) {
15
+ console.error("⚠️ [HoneyWeb] Error: HONEYWEB_API_KEY is missing from environment variables.");
16
+ }
17
+
18
+ const TRAP_PATHS = ['/admin-backup-v2', '/wp-login-hidden', '/db-dump-2024', '/auth/root-access'];
19
+
20
+ // Brute Force Config
21
+ const RATE_LIMIT_WINDOW = 10000; // 10s
22
+ const MAX_REQUESTS = 50;
23
+ const trafficMap = new Map();
24
+
25
+ // NEW: SQL Injection & XSS Patterns (The WAF)
26
+ const MALICIOUS_PATTERNS = [
27
+ /(\%27)|(\')|(\-\-)|(\%23)|(#)/i, // SQLi: ' -- #
28
+ /((\%3D)|(=))[^\n]*((\%27)|(\')|(\-\-)|(\%3B)|(;))/i, // SQLi: = ' ;
29
+ /\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/i, // SQLi: ' OR
30
+ /(<script>)/i, // XSS
31
+ /(alert\()/i // XSS
21
32
  ];
22
33
 
34
+ // Ensure DB exists
23
35
  if (!fs.existsSync(DB_FILE)) { fs.writeJsonSync(DB_FILE, []); }
24
36
 
25
37
  // ------------------------------------------------------
26
- // AI REPORTING FUNCTION
38
+ // 2. AI INTELLIGENCE
27
39
  // ------------------------------------------------------
28
- async function generateThreatReport(ip, userAgent, trapPath) {
29
- // If you haven't pasted the key yet, skip AI to prevent crash
30
- if (GOOGLE_API_KEY === 'YOUR_GOOGLE_API_KEY_HERE') {
31
- console.log("⚠️ [HoneyWeb] No Google API Key found. Skipping AI Report.");
32
- return;
33
- }
34
-
35
- console.log("🤖 [HoneyWeb] Asking Gemini to analyze the attack...");
36
-
40
+ async function generateThreatReport(ip, userAgent, type, details) {
41
+ if (!GOOGLE_API_KEY || GOOGLE_API_KEY.includes('YOUR_KEY')) return;
42
+ console.log(`🤖 [HoneyWeb] Asking Gemini to analyze: ${type}...`);
37
43
  try {
38
44
  const genAI = new GoogleGenerativeAI(GOOGLE_API_KEY);
39
-
40
45
  const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
41
-
42
- const prompt = `
43
- You are a cybersecurity analyst. Analyze this bot attack caught by a honeypot.
44
-
45
- Attack Details:
46
- - IP Address: ${ip}
47
- - User-Agent: ${userAgent}
48
- - Trap Link Accessed: ${trapPath}
49
-
50
- Please provide a 1-sentence summary of what kind of threat this is (e.g., reconnaissance, targeted scan) and what they were likely looking for.
51
- `;
52
-
46
+ const prompt = `Cybersecurity Alert. Analyze this blocked attack.
47
+ Type: ${type} | IP: ${ip} | UA: ${userAgent} | Detail: ${details}
48
+ Respond in 1 sentence: What is the attacker trying to exploit?`;
49
+
53
50
  const result = await model.generateContent(prompt);
54
- const report = result.response.text();
55
-
56
51
  console.log("\n📝 [HoneyWeb INTELLIGENCE REPORT]");
57
52
  console.log("---------------------------------------------------");
58
- console.log(report.trim());
53
+ console.log(result.response.text().trim());
59
54
  console.log("---------------------------------------------------\n");
55
+ } catch (e) { console.error("❌ Gemini Error:", e.message); }
56
+ }
60
57
 
61
- } catch (error) {
62
- // Detailed error logging to help you debug
63
- console.error("❌ [HoneyWeb] Gemini Analysis Failed:", error.message);
58
+ // ------------------------------------------------------
59
+ // 3. HELPER: BAN SYSTEM
60
+ // ------------------------------------------------------
61
+ async function banIP(ip, reason) {
62
+ let list = [];
63
+ try { list = await fs.readJson(DB_FILE); } catch (e) {}
64
+
65
+ // Check if IP is already in the list (simple check)
66
+ const exists = list.some(entry => entry.ip === ip);
67
+
68
+ if (!exists) {
69
+ list.push({ ip, reason, date: new Date().toISOString() });
70
+ await fs.writeJson(DB_FILE, list);
71
+ console.log(`🚫 [HoneyWeb] BANNED IP: ${ip} | Reason: ${reason}`);
72
+ return true;
64
73
  }
74
+ return false;
65
75
  }
66
76
 
67
77
  // ------------------------------------------------------
68
- // MIDDLEWARE LOGIC
78
+ // 4. MAIN MIDDLEWARE
69
79
  // ------------------------------------------------------
70
80
  function honeyWeb() {
71
81
  return async (req, res, next) => {
72
82
  const clientIP = req.ip || req.connection.remoteAddress;
83
+ const userAgent = req.headers['user-agent'] || 'Unknown';
84
+
85
+ // A. STATUS DASHBOARD
86
+ if (req.path === '/honeyweb-status') {
87
+ // Insert your own secret key here
88
+ // Usage: http://localhost:3000/honeyweb-status?key=admin123
89
+ if (req.query.key !== 'admin123') {
90
+ return res.status(404).send('Not Found'); // Pretend it doesn't exist
91
+ }
92
+
93
+ const list = await fs.readJson(DB_FILE);
94
+ return res.send(`
95
+ <html><body style="font-family:monospace; background:#222; color:#0f0; padding:20px;">
96
+ <h1>🛡️ HoneyWeb Active Defense Status</h1>
97
+ <p>Total Banned IPs: ${list.length}</p>
98
+ <table border="1" style="border-collapse:collapse; width:100%; color:#fff;">
99
+ <tr><th>IP</th><th>Reason</th><th>Time</th></tr>
100
+ ${list.map(i => `<tr><td>${i.ip}</td><td>${i.reason}</td><td>${i.date}</td></tr>`).join('')}
101
+ </table></body></html>
102
+ `);
103
+ }
73
104
 
74
- // 1. Check Blocklist
75
- let bannedIPs = [];
76
- try { bannedIPs = await fs.readJson(DB_FILE); } catch (e) {}
105
+ // B. CHECK BLOCKLIST
106
+ let bannedList = [];
107
+ try { bannedList = await fs.readJson(DB_FILE); } catch (e) {}
108
+ if (bannedList.some(entry => entry.ip === clientIP)) {
109
+ return res.status(403).send('<h1>403 Forbidden</h1><p>Your IP is flagged by HoneyWeb.</p>');
110
+ }
77
111
 
78
- if (bannedIPs.includes(clientIP)) {
79
- return res.status(403).send('<h1>403 Forbidden</h1><p>Banned by HoneyWeb.</p>');
112
+ // C. ANTI-BRUTE FORCE (Rate Limit)
113
+ const now = Date.now();
114
+ if (!trafficMap.has(clientIP)) trafficMap.set(clientIP, { count: 1, start: now });
115
+ else {
116
+ const data = trafficMap.get(clientIP);
117
+ if (now - data.start > RATE_LIMIT_WINDOW) trafficMap.set(clientIP, { count: 1, start: now });
118
+ else {
119
+ data.count++;
120
+ if (data.count > MAX_REQUESTS) {
121
+ if (await banIP(clientIP, "Brute Force (Rate Limit Exceeded)")) {
122
+ generateThreatReport(clientIP, userAgent, "Volumetric Attack", `> ${MAX_REQUESTS} reqs/10s`);
123
+ }
124
+ return res.status(429).send('Too Many Requests');
125
+ }
126
+ }
80
127
  }
81
128
 
82
- // 2. Check Trap
83
- if (TRAP_PATHS.includes(req.path)) {
84
- console.log(`[HoneyWeb] 🚨 TRAP TRIGGERED by ${clientIP}`);
85
-
86
- if (!bannedIPs.includes(clientIP)) {
87
- bannedIPs.push(clientIP);
88
- await fs.writeJson(DB_FILE, bannedIPs);
129
+ // D. BAIT PARAMETER ANALYSIS (Smarter WAF)
130
+
131
+ const checkPayload = (str) => {
132
+ if (!str) return false;
133
+ return MALICIOUS_PATTERNS.some(regex => regex.test(str));
134
+ };
135
+
136
+ // Scan URL Query Params (?id=1 OR 1=1)
137
+ if (checkPayload(req.originalUrl)) {
138
+ if (await banIP(clientIP, "Malicious URL Payload")) {
139
+ generateThreatReport(clientIP, userAgent, "Injection Attack", `Dirty URL: ${req.originalUrl}`);
89
140
  }
141
+ return res.status(403).send('Forbidden');
142
+ }
143
+
144
+ // Scan specific "Login" fields only (Reduces false positives on other forms)
145
+ if (req.method === 'POST' && req.body) {
146
+ const riskyInputs = [req.body.username, req.body.password, req.body.search];
147
+ if (riskyInputs.some(input => checkPayload(input))) {
148
+ if (await banIP(clientIP, "Malicious Form Data")) {
149
+ generateThreatReport(clientIP, userAgent, "SQL Injection", `Payload in form: ${JSON.stringify(req.body)}`);
150
+ }
151
+ return res.status(403).send('Forbidden');
152
+ }
153
+ }
90
154
 
91
- // Trigger AI Analysis
92
- generateThreatReport(clientIP, req.headers['user-agent'], req.path);
155
+ // E. HONEYPOT TRAP
156
+ if (TRAP_PATHS.includes(req.path)) {
157
+ if (await banIP(clientIP, "Trap Triggered")) {
158
+ generateThreatReport(clientIP, userAgent, "Reconnaissance", `Accessed trap: ${req.path}`);
159
+
160
+ // detect browser of attacker and other info (hardware?) for logging
93
161
 
162
+
163
+ }
94
164
  return res.status(403).send('<h1>403 Forbidden</h1>');
95
165
  }
96
166
 
97
- // 3. Inject Hidden Links
167
+ // F. INJECTION
98
168
  const originalSend = res.send;
99
169
  res.send = function (body) {
100
- if (typeof body === 'string' && (body.includes('<html') || body.includes('<body'))) {
170
+ if (typeof body === 'string' && (body.includes('<body') || body.includes('<html'))) {
101
171
  const $ = cheerio.load(body);
172
+
173
+ // Select a random trap URL
102
174
  const trapUrl = TRAP_PATHS[Math.floor(Math.random() * TRAP_PATHS.length)];
103
- $('body').append(`<a href="${trapUrl}" style="opacity:0; position:absolute; z-index:-999;">Admin</a>`);
175
+
176
+ // Inject CSS that mimics standard Accessibility Hiding (Bootstrap/Tailwind style)
177
+ // This reduces the element to a 1x1 pixel clip that is technically "visible" but unclickable.
178
+ const cssCamouflage = `
179
+ <style>
180
+ .sr-only-utility {
181
+ position: absolute;
182
+ width: 1px;
183
+ height: 1px;
184
+ padding: 0;
185
+ margin: -1px;
186
+ overflow: hidden;
187
+ clip: rect(0, 0, 0, 0);
188
+ white-space: nowrap;
189
+ border: 0;
190
+ }
191
+ </style>
192
+ `;
193
+
194
+ // Inject the link with a boring name ("Skip to content", "Toolbar")
195
+ // A bot sees this as a valid navigation aid.
196
+ $('head').append(cssCamouflage);
197
+ $('body').prepend(`<a href="${trapUrl}" class="sr-only-utility">Skip to Content</a>`);
198
+
104
199
  body = $.html();
105
200
  }
106
201
  originalSend.call(this, body);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honeyweb-core",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/index V1.js DELETED
@@ -1,85 +0,0 @@
1
- // honeyweb-core/index.js
2
- const fs = require('fs-extra');
3
- const path = require('path');
4
- const cheerio = require('cheerio');
5
-
6
- // File path for storing banned IPs automatically
7
- const DB_FILE = path.join(__dirname, 'blocked-ips.json');
8
-
9
- // Ensure the JSON file exists on startup
10
- if (!fs.existsSync(DB_FILE)) {
11
- fs.writeJsonSync(DB_FILE, []);
12
- }
13
-
14
- // Configuration: List of fake trap paths
15
- // These look like real admin pages to a bot
16
- const TRAP_PATHS = [
17
- '/admin-backup-v2',
18
- '/wp-login-hidden',
19
- '/db-dump-2024',
20
- '/auth/root-access',
21
- '/sys/config-safe'
22
- ];
23
-
24
- /**
25
- * HoneyWeb Middleware
26
- * Usage: app.use(honeyWeb());
27
- */
28
- function honeyWeb() {
29
- return async (req, res, next) => {
30
- const clientIP = req.ip || req.connection.remoteAddress;
31
-
32
- // 1. LOAD BANNED LIST
33
- let bannedIPs = [];
34
- try {
35
- bannedIPs = await fs.readJson(DB_FILE);
36
- } catch (err) {
37
- console.error("HoneyWeb: Error reading blocklist", err);
38
- }
39
-
40
- // 2. CHECK IF IP IS ALREADY BANNED
41
- if (bannedIPs.includes(clientIP)) {
42
- console.log(`[HoneyWeb] BLOCKED access from banned IP: ${clientIP}`);
43
- return res.status(403).send('<h1>403 Forbidden</h1><p>Your IP has been flagged for suspicious activity.</p>');
44
- }
45
-
46
- // 3. CHECK IF TRAP ACCESSED
47
- if (TRAP_PATHS.includes(req.path)) {
48
- console.log(`[HoneyWeb] 🚨 TRAP TRIGGERED by ${clientIP} on ${req.path}`);
49
-
50
- // Ban the IP immediately
51
- if (!bannedIPs.includes(clientIP)) {
52
- bannedIPs.push(clientIP);
53
- await fs.writeJson(DB_FILE, bannedIPs);
54
- }
55
-
56
- return res.status(403).send('<h1>403 Forbidden</h1><p>You have accessed a restricted area.</p>');
57
- }
58
-
59
- // 4. INJECT TRAPS INTO HTML RESPONSES
60
- const originalSend = res.send;
61
-
62
- res.send = function (body) {
63
- // Only inject if the content is HTML
64
- if (typeof body === 'string' && (body.includes('<html') || body.includes('<body'))) {
65
- const $ = cheerio.load(body);
66
-
67
- // Pick a random trap
68
- const trapUrl = TRAP_PATHS[Math.floor(Math.random() * TRAP_PATHS.length)];
69
-
70
- // Create invisible link (Hidden by CSS)
71
- const trapLink = `<a href="${trapUrl}" style="opacity:0; position:absolute; z-index:-999; left:-9999px;">Admin Panel</a>`;
72
-
73
- // Inject into body
74
- $('body').append(trapLink);
75
-
76
- body = $.html();
77
- }
78
- originalSend.call(this, body);
79
- };
80
-
81
- next();
82
- };
83
- }
84
-
85
- module.exports = honeyWeb;