Skip to content

Commit

Permalink
fix: update nonce generation to use cryptographic RNG (spruceid#20)
Browse files Browse the repository at this point in the history
* fix: update nonce generation to use cryptographic RNG

* feat: add support in core SIWE lib to generate nonces

* add new line character  for consistency

Co-authored-by: Gregório Granado Magalhães <[email protected]>

Co-authored-by: Gregório Granado Magalhães <[email protected]>
  • Loading branch information
kdenhartog and w4ll3 authored Nov 29, 2021
1 parent 482aa32 commit 00a0f07
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 5 deletions.
5 changes: 4 additions & 1 deletion examples/notepad/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/notepad/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@
"webpack": "^5.64.0",
"webpack-cli": "^4.9.1"
}
}
}
4 changes: 2 additions & 2 deletions examples/notepad/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Helmet from 'helmet';
import Morgan from 'morgan';
import Path from 'path';
import FileStore from 'session-file-store';
import { ErrorTypes, SiweMessage } from 'siwe';
import { ErrorTypes, SiweMessage, generateNonce } from 'siwe';
const FileStoreStore = FileStore(Session);

config();
Expand Down Expand Up @@ -70,7 +70,7 @@ app.use(
app.use(Express.static(Path.resolve(__dirname, '../public')));

app.get('/api/nonce', async (req, res) => {
req.session.nonce = (Math.random() + 1).toString(36).substring(4);
req.session.nonce = generateNonce();
req.session.save(() => res.status(200).send(req.session.nonce).end());
});

Expand Down
19 changes: 18 additions & 1 deletion lib/client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

import { randomStringForEntropy } from '@stablelib/random';
// TODO: Figure out how to get types from this lib:
import { Contract, ethers, utils } from 'ethers';
import { ParsedMessage as ABNFParsedMessage } from './abnf';
Expand Down Expand Up @@ -114,7 +116,7 @@ export class SiweMessage {
const versionField = `Version: ${this.version}`;

if (!this.nonce) {
this.nonce = (Math.random() + 1).toString(36).substring(4);
this.nonce = generateNonce();
}

const chainField = `Chain ID: ` + this.chainId || "1";
Expand Down Expand Up @@ -281,3 +283,18 @@ export const checkContractWalletSignature = async (
throw e;
}
};

/**
* This method leverages a native CSPRNG with support for both browser and Node.js
* environments in order generate a cryptographically secure nonce for use in the
* SiweMessage in order to prevent replay attacks.
*
* 96 bits has been chosen as a number to sufficiently balance size and security considerations
* relative to the lifespan of it's usage.
*
* @returns cryptographically generated random nonce with 96 bits of entropy encoded with
* an alphanumeric character set.
*/
export const generateNonce = (): string => {
return randomStringForEntropy(96);
}
55 changes: 55 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"typescript": "^4.4.4"
},
"dependencies": {
"@stablelib/random": "^1.0.1",
"apg-js": "^4.1.1",
"ethers": "^5.5.1"
}
Expand Down

0 comments on commit 00a0f07

Please sign in to comment.