@blamejs/blamejs-shop 0.4.109 → 0.4.110
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/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/payment.js +5 -5
- package/lib/r2-bridge.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
|
|
|
8
8
|
|
|
9
9
|
## v0.4.x
|
|
10
10
|
|
|
11
|
+
- v0.4.110 (2026-06-26) — **Inbound webhook bodies and external API responses are parsed through the size-bounded, prototype-pollution-stripping JSON primitive instead of a raw parse.** The remaining places that parsed externally-supplied JSON with a raw JSON.parse — the Stripe and PayPal inbound webhook bodies, the captcha provider's verification response, and the Stripe / PayPal / R2 API responses — now route through the framework's safe-JSON parser, which strips prototype-pollution keys ("__proto__") and bounds parse depth, key count, and byte size. This matters most for the PayPal webhook body, which is parsed up front before its signature is verified, and for every inbound or provider response that previously had no size bound. An audit confirmed the rest of the app's JSON parsing already reads only values it wrote itself to the database (validated at write time) or already used the safe parser, so those are unchanged. Valid payloads parse identically; a malformed, prototype-pollution-laden, or oversized body is now defused. No configuration changes. **Changed:** *Externally-supplied JSON (webhook bodies, provider responses) is parsed with the safe-JSON primitive* — The inbound Stripe and PayPal webhook bodies, the captcha siteverify response, and the Stripe / PayPal / R2 API responses were parsed with a raw JSON.parse, which keeps a "__proto__" member as an own key and imposes no size bound. These now route through the framework's safe-JSON parser (prototype-pollution-key strip + depth / key / size caps), so an inbound or external payload can no longer carry a prototype-pollution gadget or force an unbounded parse — notably the PayPal webhook body, which is decoded before its signature is verified. The change is parse-only: valid payloads decode exactly as before, each call keeps its existing error fallback, and the rest of the app's JSON parsing (values it serialized to its own database, validated at write time) is left as-is.
|
|
12
|
+
|
|
11
13
|
- v0.4.109 (2026-06-26) — **Vendored framework refreshed to 0.15.29.** Updates the vendored blamejs framework to 0.15.29, an upstream security-hardening release. Upstream now routes the parsing of operator- and untrusted-supplied JSON through the framework's safe-JSON primitive — which strips prototype-pollution keys ("__proto__" and friends) and bounds parse depth, key count, and byte size — instead of a raw JSON.parse, across the OpenAPI and AsyncAPI document parsers, the sandbox result decoder, and the internal sealed-store and VEX parses. This storefront consumes those surfaces through the vendored framework, so the hardening applies on upgrade with no API or configuration change and no operator action required. Valid input parses identically; a "__proto__"-laden or oversized payload is defused. **Changed:** *Vendored framework refreshed to 0.15.29* — Refreshes the vendored blamejs framework to 0.15.29. Upstream routes operator- and untrusted-supplied JSON through the safe-JSON primitive (prototype-pollution-key strip + depth / key / size caps, fail-closed) rather than a raw JSON.parse — in the OpenAPI / AsyncAPI parsers, the sandbox result decoder, and the internal sealed-store and VEX parses — and adds a parse-string-or-object helper so a raw JSON.parse on operator input can't be reintroduced one call site at a time. Valid documents are unaffected; a prototype-pollution-laden or oversized payload is now stripped and bounded. No runtime API change and no operator action required.
|
|
12
14
|
|
|
13
15
|
- v0.4.108 (2026-06-26) — **Vendored framework refreshed to 0.15.28.** Updates the vendored blamejs framework to 0.15.28. The upstream change corrects the terminal-vs-transient retry signal (err.permanent) on the framework's DNS and TLS network errors, so the vendored HTTP client's internal retry behavior only re-attempts failures a retry can actually fix and stops retrying hopeless ones. This storefront consumes those network primitives only transitively through the vendored HTTP client (payment-provider and outbound-webhook calls), so the improvement applies automatically with no API or configuration change and no operator action required. **Changed:** *Vendored framework refreshed to 0.15.28* — Refreshes the vendored blamejs framework to 0.15.28. Upstream, the DNS and TLS network errors now expose a correct err.permanent flag (fail-closed: an unknown code is treated as permanent), so a retry loop re-attempts only transient network round-trip failures and never spins on a permanent one — while a trust-verification failure stays terminal and is never silently retried. This storefront uses these primitives only through the vendored HTTP client, so the better retry behavior applies transitively to payment-provider and outbound-webhook calls; there is no API change and no operator action required.
|
package/lib/asset-manifest.json
CHANGED
package/lib/payment.js
CHANGED
|
@@ -280,7 +280,7 @@ async function _verifyWebhook(headers, rawBody, secret, opts) {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
try {
|
|
283
|
-
return { ok: true, event:
|
|
283
|
+
return { ok: true, event: b.safeJson.parse(rawBody) };
|
|
284
284
|
} catch (_e) {
|
|
285
285
|
return { ok: false, reason: "bad-json" };
|
|
286
286
|
}
|
|
@@ -335,7 +335,7 @@ async function _stripeCall(opts, method, path, params, idempotencyKey) {
|
|
|
335
335
|
});
|
|
336
336
|
var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
|
|
337
337
|
var parsed = null;
|
|
338
|
-
try { parsed = text.length ?
|
|
338
|
+
try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
|
|
339
339
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
340
340
|
var err = new Error("stripe: " + method + " " + path + " → HTTP " + res.statusCode +
|
|
341
341
|
(parsed && parsed.error && parsed.error.message ? " — " + parsed.error.message : ""));
|
|
@@ -919,7 +919,7 @@ async function _paypalToken(opts, state) {
|
|
|
919
919
|
allowedHosts: [_paypalAllowedHost(opts)],
|
|
920
920
|
});
|
|
921
921
|
var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
|
|
922
|
-
var parsed; try { parsed = text.length ?
|
|
922
|
+
var parsed; try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = {}; }
|
|
923
923
|
if (res.statusCode < 200 || res.statusCode >= 300 || !parsed.access_token) {
|
|
924
924
|
var err = new Error("paypal: OAuth2 token exchange failed → HTTP " + res.statusCode +
|
|
925
925
|
(parsed && parsed.error_description ? " — " + parsed.error_description : ""));
|
|
@@ -974,7 +974,7 @@ async function _paypalCall(opts, state, method, path, bodyObj, requestId, breake
|
|
|
974
974
|
allowedHosts: [allowedHost],
|
|
975
975
|
});
|
|
976
976
|
var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
|
|
977
|
-
var parsed; try { parsed = text.length ?
|
|
977
|
+
var parsed; try { parsed = text.length ? b.safeJson.parse(text) : {}; } catch (_e) { parsed = { _raw: text }; }
|
|
978
978
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
979
979
|
var detail = parsed && (parsed.message || (parsed.details && parsed.details[0] && parsed.details[0].description)) || "";
|
|
980
980
|
var err = new Error("paypal: " + method + " " + path + " → HTTP " + res.statusCode + (detail ? " — " + detail : ""));
|
|
@@ -1130,7 +1130,7 @@ function paypal(opts) {
|
|
|
1130
1130
|
return { ok: false, reason: "missing-transmission-headers" };
|
|
1131
1131
|
}
|
|
1132
1132
|
var event;
|
|
1133
|
-
try { event = typeof rawBody === "string" ?
|
|
1133
|
+
try { event = typeof rawBody === "string" ? b.safeJson.parse(rawBody) : rawBody; }
|
|
1134
1134
|
catch (_e) { return { ok: false, reason: "malformed-body" }; }
|
|
1135
1135
|
var verifyBody = {
|
|
1136
1136
|
auth_algo: authAlgo,
|
package/lib/r2-bridge.js
CHANGED
|
@@ -140,7 +140,7 @@ function create(opts) {
|
|
|
140
140
|
}
|
|
141
141
|
var text = res.body && res.body.toString ? res.body.toString("utf8") : "";
|
|
142
142
|
var json = null;
|
|
143
|
-
try { json = text.length ?
|
|
143
|
+
try { json = text.length ? b.safeJson.parse(text) : null; } catch (_e) { json = null; }
|
|
144
144
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
145
145
|
var err = _httpErr(res.statusCode, "upload");
|
|
146
146
|
if (json && json.error) {
|
package/package.json
CHANGED