capjs-core 0.1.1 → 0.1.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.
- package/package.json +1 -1
- package/src/index.js +1 -8
- package/src/instrumentation.js +27 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capjs-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Stateless server-side challenge generator and verifier for Cap, a lightweight, modern open-source CAPTCHA alternative. No storage, no filesystem - bring your own.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anti-abuse",
|
package/src/index.js
CHANGED
|
@@ -27,13 +27,9 @@ export {
|
|
|
27
27
|
|
|
28
28
|
const DEFAULT_RSW_T = 75_000;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
// pass the same `keypair` object back across requests get zero per-call
|
|
32
|
-
// overhead beyond the mint itself.
|
|
33
|
-
const _minterCache = new WeakMap(); // keypair → Map<t, minter>
|
|
30
|
+
const _minterCache = new WeakMap();
|
|
34
31
|
|
|
35
32
|
function resolveRswMinter(opts) {
|
|
36
|
-
// explicit minter takes precedence (existing API)
|
|
37
33
|
if (opts.rsw && typeof opts.rsw.mint === "function") return opts.rsw;
|
|
38
34
|
|
|
39
35
|
if (!opts.keypair) {
|
|
@@ -42,13 +38,10 @@ function resolveRswMinter(opts) {
|
|
|
42
38
|
);
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
// Normalize: serialized (strings) → BigInt
|
|
46
41
|
const kp = typeof opts.keypair.N === "string"
|
|
47
42
|
? deserializeRswKeypair(opts.keypair)
|
|
48
43
|
: opts.keypair;
|
|
49
44
|
|
|
50
|
-
// Memoize {keypair, t} → minter. Reuses the precomputed h across calls so
|
|
51
|
-
// the first request after boot is the only one that pays the ~5 ms setup.
|
|
52
45
|
const t = opts.t ?? DEFAULT_RSW_T;
|
|
53
46
|
let byT = _minterCache.get(opts.keypair);
|
|
54
47
|
if (!byT) {
|
package/src/instrumentation.js
CHANGED
|
@@ -151,6 +151,25 @@ const DOC_PROP_MARKERS = [
|
|
|
151
151
|
"__webdriver_script_func",
|
|
152
152
|
"__webdriver_script_function",
|
|
153
153
|
];
|
|
154
|
+
const NAV_OWN_PROP_MARKERS = [
|
|
155
|
+
"webdriver",
|
|
156
|
+
"userAgent",
|
|
157
|
+
"appVersion",
|
|
158
|
+
"userAgentData",
|
|
159
|
+
"platform",
|
|
160
|
+
"vendor",
|
|
161
|
+
"product",
|
|
162
|
+
"productSub",
|
|
163
|
+
"languages",
|
|
164
|
+
"language",
|
|
165
|
+
"plugins",
|
|
166
|
+
"mimeTypes",
|
|
167
|
+
"hardwareConcurrency",
|
|
168
|
+
"deviceMemory",
|
|
169
|
+
"maxTouchPoints",
|
|
170
|
+
"permissions",
|
|
171
|
+
"connection",
|
|
172
|
+
];
|
|
154
173
|
const ATTR_SUBSTRING_MARKERS = ["selenium", "webdriver", "driver"];
|
|
155
174
|
const STACK_SUBSTRING_MARKERS = ["pptr:", "UtilityScript.", "PhantomJS"];
|
|
156
175
|
const WINDOW_PREFIX_MARKERS = ["puppeteer_", "cdc_", "$cdc_"];
|
|
@@ -179,6 +198,7 @@ function hashWith(seed) {
|
|
|
179
198
|
function buildBlockChecks(b, id, hF, hSet, h) {
|
|
180
199
|
const winHashes = WINDOW_PROP_MARKERS.map(h);
|
|
181
200
|
const docHashes = DOC_PROP_MARKERS.map(h);
|
|
201
|
+
const navOwnHashes = NAV_OWN_PROP_MARKERS.map(h);
|
|
182
202
|
const attrSubHashes = ATTR_SUBSTRING_MARKERS.map(h);
|
|
183
203
|
const stackSubHashes = STACK_SUBSTRING_MARKERS.map(h);
|
|
184
204
|
const winPrefixHashes = WINDOW_PREFIX_MARKERS.map(h);
|
|
@@ -187,16 +207,19 @@ function buildBlockChecks(b, id, hF, hSet, h) {
|
|
|
187
207
|
const webglRendererHash = h(WEBGL_RENDERER_MARKER);
|
|
188
208
|
const productSubGeckoHash = h(PRODUCTSUB_GECKO);
|
|
189
209
|
const sequentumHash = h(SEQUENTUM_MARKER);
|
|
190
|
-
|
|
210
|
+
|
|
191
211
|
const checks = [];
|
|
192
212
|
|
|
193
213
|
checks.push(
|
|
194
214
|
`if (!${b}) { try { var d = Object.getOwnPropertyDescriptors(navigator); var __wh = ${h("webdriver")}; for (const k in d) { if (${hF}(k) === __wh) { ${b} = true; break; } } if (!${b}) { var p = Object.getPrototypeOf(navigator); while (p && !${b}) { for (const k of Object.getOwnPropertyNames(p)) { if (${hF}(k) === __wh) { try { if (navigator[k]) ${b} = true; } catch {} break; } } p = Object.getPrototypeOf(p); } } } catch { ${b} = true; } }`,
|
|
195
215
|
);
|
|
196
216
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
217
|
+
{
|
|
218
|
+
const a = rVar();
|
|
219
|
+
checks.push(
|
|
220
|
+
`if (!${b}) { try { var ${a} = ${JSON.stringify(navOwnHashes)}; for (const k of Object.getOwnPropertyNames(navigator)) { if (${hSet}(${a}, ${hF}(k))) { ${b} = true; break; } } } catch { ${b} = true; } }`,
|
|
221
|
+
);
|
|
222
|
+
}
|
|
200
223
|
|
|
201
224
|
{
|
|
202
225
|
const a = rVar();
|