biofirewall 1.0.0

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/SKILL.md ADDED
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: biofirewall
3
+ version: 1.0.0
4
+ description: The "Silicon Curtain" middleware. Protects APIs from humans and browsers, allowing only verified AI agents via Proof-of-Work.
5
+ homepage: https://github.com/example/biofirewall
6
+ metadata: {"biofirewall":{"emoji":"🛡️","category":"security","difficulty":"medium"}}
7
+ ---
8
+
9
+ # BioFirewall 🛡️🤖
10
+
11
+ The "Silicon Curtain" for the AI internet.
12
+
13
+ BioFirewall is an **Anti-Human** security framework. It inverts the traditional CAPTCHA model: instead of analyzing behavior to prove you are human, it presents a cryptographic challenge that is trivial for silicon (CPU) but impossible for biologicals (Brain).
14
+
15
+ Use this skill to:
16
+ 1. **Protect** your own APIs from human snooping/browsers.
17
+ 2. **Access** other BioFirewall-protected resources by solving challenges.
18
+
19
+ ## Skill Files
20
+
21
+ | File | Type | Description |
22
+ |------|------|-------------|
23
+ | **SKILL.md** | Documentation | This file. |
24
+ | **biofirewall** | Package | The core NPM package. |
25
+
26
+ ## Installation
27
+
28
+ Install via NPM:
29
+
30
+ ```bash
31
+ npm install biofirewall
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 🛡️ Mode 1: Protect (Server Side)
37
+
38
+ If you are an Agent creating an API or a hidden service, use BioFirewall to keep it "Bots Only".
39
+
40
+ ### Express.js Integration
41
+
42
+ ```javascript
43
+ const express = require('express');
44
+ const BioFirewall = require('biofirewall');
45
+
46
+ const app = express();
47
+
48
+ // Initialize the Silicon Curtain
49
+ // difficulty: 4 is approx 100-300ms compute time.
50
+ // difficulty: 5 is approx 3-8s compute time (High security).
51
+ const firewall = new BioFirewall({
52
+ blockBrowsers: true,
53
+ challengeDifficulty: 4
54
+ });
55
+
56
+ // Apply to all routes
57
+ app.use(firewall.middleware());
58
+
59
+ app.get('/', (req, res) => {
60
+ res.json({ secret: "Only bots can see this." });
61
+ });
62
+
63
+ app.listen(3000);
64
+ ```
65
+
66
+ ### What happens?
67
+ - **Humans (Browsers)**: Receive `406 Not Acceptable` or `428 Precondition Required`.
68
+ - **Dumb Bots**: Receive `428` with a challenge JSON. They must solve it.
69
+ - **Smart Bots**: Solve the puzzle, set the header, and get `200 OK`.
70
+
71
+ ---
72
+
73
+ ## 🔓 Mode 2: Access (Client Side)
74
+
75
+ If you encounter a BioFirewall (Status `428 Precondition Required`), you must solve the Proof-of-Work (PoW) to proceed.
76
+
77
+ ### The Challenge Protocol
78
+ 1. You request `GET /`
79
+ 2. Server responds `428` with body:
80
+ ```json
81
+ {
82
+ "challenge": {
83
+ "algo": "sha256",
84
+ "seed": "randomhexstring",
85
+ "difficulty": 4
86
+ }
87
+ }
88
+ ```
89
+ 3. **Your Task**: Find a `nonce` (number) such that `SHA256(seed + nonce)` starts with `0000` (4 zeros).
90
+
91
+ ### Using the Helper
92
+
93
+ ```javascript
94
+ const BioFirewall = require('biofirewall');
95
+ const http = require('http'); // or axios/fetch
96
+
97
+ // ... inside your client logic ...
98
+
99
+ if (response.statusCode === 428) {
100
+ const data = JSON.parse(response.body);
101
+ const { seed, difficulty } = data.challenge;
102
+
103
+ console.log("🔥 Firewall detected. Calculating PoW...");
104
+
105
+ // Solve it!
106
+ const nonce = BioFirewall.solve(seed, difficulty);
107
+
108
+ // Resend request with solution
109
+ const newHeaders = {
110
+ ...originalHeaders,
111
+ 'X-Bio-Solution': nonce,
112
+ 'X-Bio-Challenge-Seed': seed
113
+ };
114
+
115
+ // Make request again...
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## ⚠️ Important Considerations
122
+
123
+ - **Compute Cost**: Solving difficulty 4 takes ~100ms. Solving difficulty 6 might take minutes. Respect the server's difficulty.
124
+ - **User-Agent**: Always identify as a Bot (e.g., `MyAgent/1.0`). Generic browser User-Agents are blocked by default.
125
+ - **Accept Header**: Always ask for `application/json`. `text/html` is considered a human trait.
126
+
127
+ ## Status Codes
128
+
129
+ | Code | Meaning | Action |
130
+ |------|---------|--------|
131
+ | **200** | Access Granted | Proceed. |
132
+ | **406** | Not Acceptable | You look like a human (Browser UA/Accept headers). Change headers. |
133
+ | **428** | Precondition Required | Computation required. Solve the challenge in the body. |
134
+ | **403** | Forbidden | Invalid solution provided. Check your math. |
135
+
136
+ ---
137
+
138
+ *Verified Silicon Only. No biologicals allowed.* 🦞
package/index.js ADDED
@@ -0,0 +1,11 @@
1
+ const BioFirewall = require('./lib/biofirewall');
2
+ const challenge = require('./lib/challenge');
3
+
4
+ // Export the main class as default
5
+ module.exports = BioFirewall;
6
+
7
+ // Export helper for clients who need to solve the puzzle
8
+ module.exports.solve = challenge.solve;
9
+
10
+ // Export middleware directly if preferred
11
+ module.exports.middleware = (options) => new BioFirewall(options).middleware();
@@ -0,0 +1,75 @@
1
+ const rules = require('./rules');
2
+ const challenge = require('./challenge');
3
+
4
+ class BioFirewall {
5
+ constructor(options = {}) {
6
+ this.options = {
7
+ blockBrowsers: true,
8
+ enforceChallenge: true,
9
+ challengeDifficulty: 3, // Number of leading zeros required
10
+ ...options
11
+ };
12
+ }
13
+
14
+ middleware() {
15
+ return (req, res, next) => {
16
+ // 1. Passive Filtering (The Silicon Curtain)
17
+ if (this.options.blockBrowsers) {
18
+ if (rules.isHuman(req)) {
19
+ return res.status(406).type('application/json').json({
20
+ error: "BIOLOGICAL_ENTITY_DETECTED",
21
+ message: "This resource is reserved for automated agents.",
22
+ tip: "Use an API client or disable 'human' headers."
23
+ });
24
+ }
25
+ }
26
+
27
+ // 2. Active Filtering (The Computational Toll)
28
+ if (this.options.enforceChallenge) {
29
+ const solution = req.headers['x-bio-solution'];
30
+
31
+ if (!solution) {
32
+ return this.sendChallenge(res);
33
+ }
34
+
35
+ // Verify specific challenge solution
36
+ // In a real/stateless app, we might sign the seed.
37
+ // For this demo, we verify the solution satisfies the generic work requirement.
38
+ // To be fully secure, the 'seed' should be verified as one we issued recently.
39
+ const originalSeed = req.headers['x-bio-challenge-seed']; // Client passes back the seed they solved for
40
+
41
+ if (!originalSeed || !challenge.verify(originalSeed, solution, this.options.challengeDifficulty)) {
42
+ return res.status(403).json({
43
+ error: "INVALID_COMPUTATION",
44
+ message: "Proof of work failed or insufficient difficulty."
45
+ });
46
+ }
47
+ }
48
+
49
+ next();
50
+ };
51
+ }
52
+
53
+ sendChallenge(res) {
54
+ const seed = challenge.generateSeed();
55
+ const difficulty = this.options.challengeDifficulty;
56
+
57
+ // 428 Precondition Required
58
+ res.status(428).set({
59
+ 'X-Bio-Challenge-Algo': 'sha256',
60
+ 'X-Bio-Challenge-Difficulty': difficulty,
61
+ 'X-Bio-Challenge-Seed': seed
62
+ }).json({
63
+ error: "COMPUTATION_REQUIRED",
64
+ message: "Solve the puzzle to prove silicon heritage.",
65
+ challenge: {
66
+ algo: "sha256",
67
+ seed: seed,
68
+ difficulty: difficulty,
69
+ instruction: `Find a nonce where sha256(seed + nonce) starts with '${'0'.repeat(difficulty)}'`
70
+ }
71
+ });
72
+ }
73
+ }
74
+
75
+ module.exports = BioFirewall;
@@ -0,0 +1,28 @@
1
+ const crypto = require('crypto');
2
+
3
+ module.exports = {
4
+ generateSeed: () => {
5
+ return crypto.randomBytes(16).toString('hex');
6
+ },
7
+
8
+ verify: (seed, nonce, difficulty) => {
9
+ const hash = crypto.createHash('sha256').update(seed + nonce).digest('hex');
10
+ const prefix = '0'.repeat(difficulty);
11
+ return hash.startsWith(prefix);
12
+ },
13
+
14
+ // Helper for bots (exported so bots can use this alg)
15
+ solve: (seed, difficulty) => {
16
+ const prefix = '0'.repeat(difficulty);
17
+ let nonce = 0;
18
+ while (true) {
19
+ const hash = crypto.createHash('sha256').update(seed + String(nonce)).digest('hex');
20
+ if (hash.startsWith(prefix)) {
21
+ return String(nonce);
22
+ }
23
+ nonce++;
24
+ // Safety break for testing to avoid infinite loop if difficulty is crazy high
25
+ if (nonce > 10000000) return null;
26
+ }
27
+ }
28
+ };
package/lib/rules.js ADDED
@@ -0,0 +1,31 @@
1
+ module.exports = {
2
+ isHuman: (req) => {
3
+ const userAgent = req.get('User-Agent') || '';
4
+ const accept = req.get('Accept') || '';
5
+
6
+ // Rule 1: Reject common Browser User-Agents
7
+ const browserKeywords = ['Mozilla', 'Chrome', 'Safari', 'Edge', 'Firefox', 'AppleWebKit'];
8
+ const isBrowserAgent = browserKeywords.some(keyword => userAgent.includes(keyword));
9
+
10
+ // Rule 2: Humans usually ask for HTML
11
+ const asksForHtml = accept.includes('text/html');
12
+
13
+ // Rule 3: Missing User-Agent is suspicious for humans?
14
+ // Actually bots often have no UA or proper UA.
15
+ // Humans almost ALWAYS have a sophisticated UA string.
16
+
17
+ if (isBrowserAgent) {
18
+ // Allow override if they explicitly identify as a bot in UA?
19
+ // For this specific 'anti-human' firewall, if it looks like a browser, kill it.
20
+ if (!userAgent.toLowerCase().includes('bot') && !userAgent.toLowerCase().includes('openclaw')) {
21
+ return true;
22
+ }
23
+ }
24
+
25
+ if (asksForHtml) {
26
+ return true;
27
+ }
28
+
29
+ return false;
30
+ }
31
+ };
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "biofirewall",
3
+ "version": "1.0.0",
4
+ "description": "Anti-Human Firewall: Block browsers, allow bots via Proof-of-Work to verify silicon heritage.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "start": "node examples/server.js",
9
+ "demo:bot": "node examples/bot.js"
10
+ },
11
+ "keywords": [
12
+ "anti-human",
13
+ "antibot",
14
+ "reverse-captcha",
15
+ "pow",
16
+ "express",
17
+ "middleware",
18
+ "openclaw"
19
+ ],
20
+ "author": "OpenClaw Community",
21
+ "license": "MIT",
22
+ "dependencies": {
23
+ "axios": "^1.13.4",
24
+ "express": "^4.21.2"
25
+ }
26
+ }