GithubHelp home page GithubHelp logo

Comments (14)

markmhendrickson avatar markmhendrickson commented on May 27, 2024 1

If our expectation is that most messages will be less than a certain value X (e.g. 60 characters), and that their length won't require users to "click too much" (e.g. <4 clicks), then any cap we put into place for that will be irrelevant for most users.

For the few users that do encounter longer messages and more clicks, my sense is that it's better to show the full message and require more clicks, without requiring the extra step of enabling "expert mode" (and without limiting the display to only the first X characters). That way there is no possibility of "blind signing" even part of the message.

Of course, some subset of these few users may encounter many clicks (10+?) if they're signing something particular complex. But presumably that increased complexity will correlate with one's increased desire to verify the complete message and increased tolerance for clicks?

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

thanks for this clear explanation. in our case, because of the limitation the device has in regards to the characters that can be shown on the display, the ledger app only processes ASCII string messages, So users would be able to see the message they are signing. .. trying to sign a message like the one you described would cause an error.

from ledger-stacks.

kyranjamie avatar kyranjamie commented on May 27, 2024

Thanks for reporting @MarvinJanssen.

If you can help me understand the varint prefix, Stacks Signed Message:\n is 24 chars, so wouldn't that make the prefix \x18 in little endian encoding?

You describe off-chain order signing as an example of how message signing is used, but as we follow the message prefix scheme, doesn't that mute the ability to build features like this and thus prevent any similarly related attacks? What would be an abuse vector of the sign_msg function as is, or are you more concerned about the practice of signing raw input messages in general?

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

If you can help me understand the varint prefix, Stacks Signed Message:\n is 24 chars, so wouldn't that make the prefix \x18 in little endian encoding?

actually, the variant prefix is \x19

from ledger-stacks.

MarvinJanssen avatar MarvinJanssen commented on May 27, 2024

@neithanmo I see. That makes things better. In that case I suggest the JS lib to enforce this and not have it sent to the Ledger at all if there are non-printable characters present in the message. I did not dive into the Ledger code and made the report solely on the linked PR so my apologies for not going deeper.

I think the length as ASCII should still be fixed. If you make it a (var)int then you can easily determine where the actual message starts.

https://github.com/Zondax/ledger-blockstack/blob/a7a0caa8434cfda23bc54b82555db7104e0c0a3a/app/rust/src/parser/message.rs#L94

Counting digits does not work if the users inputs a message like "00", you end up with \x19Stacks Signed Message:\n200.

@kyranjamie you're right, stupid mistake on my part, 24 == \x18.

To answer your question, I was unaware that the message signing function in the firmware rejects non-ASCII messages. personal_sign was at some point in the past (ab)used to sign hashes of data structures. The ASCII prefix had nothing to do with it. They did it by hashing an ABI encoded struct and requesting a signature from the user. So the final message would look like: \x19Ethereum Signed Message:\n32<32 bytes here>. Then on the contract they would reconstruct that message to verify the signature.

Here is one such example (that I even made myself):

https://github.com/wyvernprotocol/wyvern-v3/blob/b20ae7873d3f0e9b8f5ea6d0ff3947646830dbb7/contracts/exchange/ExchangeCore.sol#L196-L201

https://github.com/wyvernprotocol/wyvern-v3/blob/b20ae7873d3f0e9b8f5ea6d0ff3947646830dbb7/contracts/exchange/ExchangeCore.sol#L25

My concern with it is that users cannot verify what they are signing. But now that I know that the Ledger app won't accept non-ASCII messages, this is less of an issue as developers will be hard pressed to (ab)use msg_sign in the same way as Eth devs did with personal_sign.

Having said all that, I still wonder what the usefulness of msg_sign is. What are the use-cases? Even more so now I heard that Hiro is working on a SIP018(-like) implementation for Hiro Wallet. You could use SIP018 to sign a string-ascii CV if you want a text message.

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

@neithanmo I see. That makes things better. In that case I suggest the JS lib to enforce this and not have it sent to the Ledger at all if there are non-printable characters present in the message. I did not dive into the Ledger code and made the report solely on the linked PR so my apologies for not going deeper.

we can add this double check as well.

I think the length as ASCII should still be fixed. If you make it a (var)int then you can easily determine where the actual message starts.

https://github.com/Zondax/ledger-blockstack/blob/a7a0caa8434cfda23bc54b82555db7104e0c0a3a/app/rust/src/parser/message.rs#L94

Counting digits does not work if the user's inputs a message like "00", you end up with \x19Stacks Signed Message:\n200.

@MarvinJanssen we considered that case as it is clearly described in the EIP-712 documentation as a possible flaw, that is why the parser verifies if \x19Stacks Signed Message:\n200 correspond to a str.len = 200 or a str = "00" with length=2. for this message the device will show the user the string "00" and will ask the user if they want to sign it.
the case for strings starting with numbers is also considered, and last but not least, trailing zeros are also invalid(there are tests for each).

there is one important thing. because of the small screen in ledger devices, and considering that string_messages can be huge. we limited the number of characters the device is going to show on the screen, which means that depending on the size of the screen and the message length, the message users see might not be a full message.

from ledger-stacks.

MarvinJanssen avatar MarvinJanssen commented on May 27, 2024

@MarvinJanssen we considered that case as it is clearly described in the EIP-712 documentation as a possible flaw, that is why the parser verifies if \x19Stacks Signed Message:\n200 correspond to a str.len = 200 or a str = "00" with length=2. for this message the device will show the user the string "00" and will ask the user if they want to sign it.

You have the opportunity to fix it, so why not fix it? There is no reason for parity with Ethereum's personal_sign.

there is one important thing. because of the small screen in ledger devices, and considering that string_messages can be huge. we limited the number of characters the device is going to show on the screen, which means that depending on the size of the screen and the message length, the message users see might not be a full message.

That sounds a little scary. Perhaps it is better if the user has to explicitly enable it, like with "blind signing" for the Ethereum Ledger app. What is the limit of how many pages of text you can show?

As an aside, what kind of huge string messages are you expecting?

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

You have the opportunity to fix it, so why not fix it? There is no reason for parity with Ethereum's personal_sign.

we have already fixed that, it is how the parser was implemented.

That sounds a little scary. Perhaps it is better if the user has to explicitly enable it, like with "blind signing" for the Ethereum Ledger app. What is the limit of how many pages of text you can show?

we can show the complete message but it would be annoying the number of times users have to click..for any message we are going to show only the first 60 characters (header not included).
What we could do for cases where strings.len > 60 is to process them only if expert mode was configured on the device. but what is a proper limit here ?

As an aside, what kind of huge string messages are you expecting?

not sure, fixing a number maybe just too much or too few for some users

from ledger-stacks.

MarvinJanssen avatar MarvinJanssen commented on May 27, 2024

What we could do for cases where strings.len > 60 is to process them only if expert mode was configured on the device. but what is a proper limit here ?

Good question. I am not sure what the feature is meant for so maybe @kyranjamie can shed light on a good limit.

from ledger-stacks.

kyranjamie avatar kyranjamie commented on May 27, 2024

@MarvinJanssen @neithanmo leather-wallet/extension#1051

I believe this issue prompted the ask of this feature.

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

i opened another issue to restrict signing messages that are longer than X bytes. If the app is in expert mode, such messages can be signed as long as they are valid. users know what they are doing so, the restriction of showing only the first X characters could remain active in both modes(I do not see an expert doing a lot of clicks)?.
To summarize:

  • in normal mode, any message longer than X would fail
  • if in expert mode longer messages are allowed.
  • in both modes, only the first X bytes are shown.

for now X = 60. the election of this number considered the nanoS screen, so a message with this length would require around ~3 clicks.

from ledger-stacks.

MarvinJanssen avatar MarvinJanssen commented on May 27, 2024

Although some upper bound surely is necessary still, lest dapps may try to send very large strings to be signed.

from ledger-stacks.

jleni avatar jleni commented on May 27, 2024

@kyranjamie @markmhx is there anything pending here?
should this result in some actions/tasks?

from ledger-stacks.

neithanmo avatar neithanmo commented on May 27, 2024

we agreed on showing the complete message to users..
please reopen if it makes sense or to start a discussion in regards to an alternative approach.

from ledger-stacks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.