@atproto/xrpc-server 0.4.0 → 0.4.1

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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # @atproto/xrpc-server
2
2
 
3
+ ## 0.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1839](https://github.com/bluesky-social/atproto/pull/1839) [`e1b5f253`](https://github.com/bluesky-social/atproto/commit/e1b5f2537a5ba4d8b951a741269b604856028ae5) Thanks [@dholms](https://github.com/dholms)! - Prevent signature malleability through DER-encoded signatures
8
+
9
+ - Updated dependencies [[`e1b5f253`](https://github.com/bluesky-social/atproto/commit/e1b5f2537a5ba4d8b951a741269b604856028ae5)]:
10
+ - @atproto/crypto@0.3.0
11
+
3
12
  ## 0.4.0
4
13
 
5
14
  ### Minor Changes
package/dist/index.js CHANGED
@@ -51925,11 +51925,23 @@ var verifyDidSig = async (did2, data, sig, opts) => {
51925
51925
  return verifySig(keyBytes, data, sig, opts);
51926
51926
  };
51927
51927
  var verifySig = async (publicKey, data, sig, opts) => {
51928
+ const allowMalleable = opts?.allowMalleableSig ?? false;
51928
51929
  const msgHash = await sha2562(data);
51930
+ if (!allowMalleable && !isCompactFormat(sig)) {
51931
+ return false;
51932
+ }
51929
51933
  return p256.verify(sig, msgHash, publicKey, {
51930
- lowS: opts?.lowS ?? true
51934
+ lowS: !allowMalleable
51931
51935
  });
51932
51936
  };
51937
+ var isCompactFormat = (sig) => {
51938
+ try {
51939
+ const parsed = p256.Signature.fromCompact(sig);
51940
+ return equals3(parsed.toCompactRawBytes(), sig);
51941
+ } catch {
51942
+ return false;
51943
+ }
51944
+ };
51933
51945
 
51934
51946
  // ../crypto/src/p256/plugin.ts
51935
51947
  var p256Plugin = {
@@ -51948,11 +51960,23 @@ var verifyDidSig2 = async (did2, data, sig, opts) => {
51948
51960
  return verifySig2(keyBytes, data, sig, opts);
51949
51961
  };
51950
51962
  var verifySig2 = async (publicKey, data, sig, opts) => {
51963
+ const allowMalleable = opts?.allowMalleableSig ?? false;
51951
51964
  const msgHash = await sha2562(data);
51965
+ if (!allowMalleable && !isCompactFormat2(sig)) {
51966
+ return false;
51967
+ }
51952
51968
  return secp256k1.verify(sig, msgHash, publicKey, {
51953
- lowS: opts?.lowS ?? true
51969
+ lowS: !allowMalleable
51954
51970
  });
51955
51971
  };
51972
+ var isCompactFormat2 = (sig) => {
51973
+ try {
51974
+ const parsed = secp256k1.Signature.fromCompact(sig);
51975
+ return equals3(parsed.toCompactRawBytes(), sig);
51976
+ } catch {
51977
+ return false;
51978
+ }
51979
+ };
51956
51980
 
51957
51981
  // ../crypto/src/secp256k1/plugin.ts
51958
51982
  var secp256k1Plugin = {
@@ -52051,7 +52075,7 @@ var verifyJwt = async (jwtStr, ownDid, getSigningKey) => {
52051
52075
  const sigBytes = fromString2(sig, "base64url");
52052
52076
  const verifySignatureWithKey = (key) => {
52053
52077
  return verifySignature(key, msgBytes, sigBytes, {
52054
- lowS: false
52078
+ allowMalleableSig: true
52055
52079
  });
52056
52080
  };
52057
52081
  const signingKey = await getSigningKey(payload.iss, false);
@@ -52500,7 +52524,7 @@ function decodeQueryParam(type, value) {
52500
52524
  if (type === "float") {
52501
52525
  return Number(String(value));
52502
52526
  } else if (type === "integer") {
52503
- return Number(String(value)) | 0;
52527
+ return parseInt(String(value), 10) || 0;
52504
52528
  } else if (type === "boolean") {
52505
52529
  return value === "true";
52506
52530
  }