dzham No, it works like Google/Twitter/Facebook OAuth.
Once you have initiated an action, a new browser window is open and the user can approve or reject the action.

5 months later
OrbitLens changed the title to StellarExpert ID – Single-Sign-On App and Tx Signer for Stellar Network .

I spent almost 6 months on the development, including 3 major refactors and multiple fixes after peer security audits. And to my mind, the result was definitely worth it, because this application may gradually simplify the life of developers (one simple interface that covers all major use cases and encapsulates other providers, like Ledger Nano, StellarGuard etc), as well as end-users (safe key management and turn-key experience across all applications).

Please check the updated project description and the demo.

How are you doing message signatures to stop people from maliciously sending regular txs, and having people sign them?

    dzham I'm going to parse the message. If it is a valid tx xdr, the signer will return an error.

    Something like

    try {
      new Transaction(xdr)
      // a valid transaction wouldn't throw an error
      return Promise.reject(new Error('Potentially malicious message.'))
    }
    catch(e) {
      return Promise.resolve(xdr)
    }

      From Reddit:

      @doomslise:
      Cool! I was planning on developing something like this for StellarGuard -- mind if I use this for inspiration?
      Additionally, would you be open to talking about integrating StellarGuard into this, as I believe it might be complementary?

      Yeah, for sure.

      1. It will be open-source.
      2. Hopefully it will be maintained by SDF, as it's the most trusted public entity on the Network.
      3. I specifically mentioned StellarGuard integration in the article.
      4. It would be great if we could integrate all existing key management and security-related solutions like StellarGuard, CosmicLink, Ledger Nano support into one single full-featured application. It will be better tested and easier to support. And Stellar application developers will need to integrate only one micro-module with standard interface to make it accessible for all Stellar users.
      5. I hope that we all can agree on the new key management standard (e.g. SEP-0011).
      6. It doesn't mean that I will be in charge of the development. I will contribute to the project working with pool requests, the same way as any other developer.

        OrbitLens

        I really like what you're doing.

        I'm trying to do this integration job with cosmic links. I recently added transparent support for StellarGuard. Right now I'm working on integrating transparent signatures sharing.

        Recently, I made the cosmic.link website compatible with Ledger Wallets, Stellar Laboratory and future Sep-0007 wallets:

        https://cosmic.link/?setOptions&inflationDest=GCCD6AJOYZCUAQLX32ZJF2MKFFAUJ53PVCFQI3RHWKL3V47QYE2BNAUT

        I'll be happy to add support for Stellar Expert Id.

        I wrote an article that have few proposals about how to work together under a common language: Understanding Cosmic Links

        I think that in the near future every wallet will have to offer such features. Would be great to agree upon simple GET/POST scheme that everybody could implement, rather than multiplying custom solutions. The reason I favor GET request despite their lack of privacy is that it works with serverless wallets.

          MisterTicot I saw your work and was really impressed by your approach. Of course it's better to agree on an unified standard than maintain multiple solutions. Your links protocol definitely makes sense for various use-cases, in particular for situations where the initiator (wallet, exchange or any other app) doesn't know user account public key in advance.

            OrbitLens Yes. Now we'll also need a way to pass the public key, and a way to login. You're the first getting there so I hope you'll bring us some neat protocol for that ?

            dzham

            Firefly only sign the pure json string to avoid this kind of scenario.

              @OrbitLens I think i am late for this article and the idea. I wrote some similar APIs for Firefly here (in Chinese only, have not translated in English yet).
              We have created some "dapps" with these APIs.

              Now I must catch up with you. it's better to agree on an unified standard than maintain multiple solutions

              OrbitLens
              dzham
              Eno

              There are other critical things that should not be signed that easily. For example the DKIF protocol allow a tier to manage a federated server on your behalf. To guarantee that the tier can't trick you, you sign the XDR federation response and make the signer key available on your DNS.

              Now I could trick someone into signing a federation response XDR that redirect to my account. This would defeat the purpose of DKIF.

              There could be other critical piece of data that could add up over time and the last thing you want is maintaining a (likely) incomplete list of checks for them.

              Now I'm not sure if we're talking about signing data for login/authentication purpose or signing arbitrary data, like in signing messages or contracts.

              For login purpose I would rather use hash(hash(x)) like Dhzam. As you know signing a text or the hash or a text might end up having a legal value, so one have to be careful here. Maybe we should restrict heavily what we accept in input.

              If the purpose is to sign abritrary data, now that's a bit complicated. Maybe transforming the data will defeat the purpose, and signing a hash of a hash as well. If it's only about signing messages and contract you could reject anything that has no space or that is accepted by JSON.parse().

              I would separate the two things in two different operations:

              ...?login&domain=external.io&callback=dex.html&challenge=...

              ...?signData&domain=external.io&callback=enter.html&data=....

              Not sure if I'm missing something. Probably I do ?

                Is there a design document that describes the protocol, so we can easily analyze its security? If SDF adopted this, we would probably a SEP that is specific enough to allow independent implementations.

                It seems you are relying on informal domain separation for signed messages--basically only sign authentication messages that don't look like transactions. This is not robust to upgrades. Hence, as a first step to integrating with the Stellar ecosystem, you should request a dedicated value of EnvelopeType as a pull request on Stellar-ledger-entries.x. (I'd maybe suggest a higher number like 20 to leave us plenty of room to extend the core protocol with things like a new transaction format.)

                  MisterTicot I just checked the sources of JS SDK signing module. It looks like it's not enough to request signing of tx envelope encoded in base 64. The signature requires specifically assembled buffer with mixed in network identifier. Nevertheless, it may be an exploitable attack vector, as a potential attacker may prepare the buffer and send it in byte encoded format resulting in a correct message signature. So @dzham's implementation is safer in this case.

                  It seems to me that using keypair.sign(hash(input_message)) will cover all possible implications, including mentioned DKIF signatures and other potentially unsafe cases.

                  Another way to achieve such result without hashing is to prepend public key to the message, using it as a salt: keypair.sign(keypair.publicKey() + input_message). It mixes public key into the signature base (somewhat faster than value hashing) and effectively prevents from signing malicious transactions.

                    mazieres The documentation is not ready yet. Hopefully, I will publish all source codes and docs in a week or so.

                    The flow is quite simple.

                    1. A user invokes some action on the third-party website (a wallet, DEX interface, inflation pool etc). Let's say, he wants to create an offer.
                    2. The website prepares the requested transaction and it's XDR representation in base64 format.
                    3. The website initiates the intent (see intent list in the project description) using js module that provides an interface for all supported intents.
                    4. The interface module opens a new pop-up window pointing to id.stellar.expert. All intent parameters are serialized and transmitted in a form of GET parameters. So the full URL will look like https://id.stellar.expert/confirm?intent=sign_tx&network=testnet&txXdr=AAAAALPZeTF82....
                    5. Signer application reads parameters from the URL and asks the user for a confirmation.
                    6. The user chooses a keypair from the list of stored accounts (or adds a new one) and confirms the action.
                    7. The signer app signs the transaction the same way any other wallet do it.
                    8. The signed transaction is serialized into XDR as TransactionEnvelope and transmitted back to the opener site in base64 encoding via the built-in browser postMessage mechanism.
                    9. The third-party website receives a signed transaction envelope and may choose either to submit it to the network or store somewhere in case if the tx needs more signatures or if it has time bounds set.

                    Intent confirmation dialog always contains extended request information, including intent description (like "Sign transaction"), initiator website ("origin: example.com"), risk level ("high", "medium", or "low"), information about personal data disclosure (only for personal_info intent), and safety status ("safe" or "potentially unsafe"). Intent-specific details allow a user to review the request before confirmation. For instance, a dialog with sing_tx intent displays full transaction information including all meaningful properties and the list of operations in a human-friendly format adapted for the ordinary users.

                    There are 4 main groups of intents:

                    1. Request transaction signing. The calling app receives a signed transaction envelope in XDR format.
                    2. Request information. The app may request a user's personal info (email, avatar), Stellar account public key, or Stellar account secret key (required only in rare cases, maybe we should disable this intent at all).
                    3. Request specific action. Currently two actions available: "vote for inflation pool" and "establish trustline". The signer app prepares and submits the transaction to the network without returning transaction envelope XDR to the initiator website. It is done to simplify such standard actions; the initiator website does not need JS SDK or any other custom logic.
                    4. Request cryptographic signature of the arbitrary data. The website may request a crypto signature to verify a keypair ownership (authentication, secure messages exchange etc).

                    If SDF adopted this, we would probably a SEP that is specific enough to allow independent implementations.

                    Absolutely agree, I'll prepare detailed documentation.

                    It seems you are relying on informal domain separation for signed messages--basically only sign authentication messages that don't look like transactions. This is not robust to upgrades. Hence, as a first step to integrating with the Stellar ecosystem, you should request a dedicated value of EnvelopeType as a pull request on Stellar-ledger-entries.x

                    I'm afraid, here you lost me... StellarExpertID is built on top of the existing SDK and it utilizes only the existing standard data formats. It's just a key storage with a simplistic interface allowing other web apps to request predefined actions. I can't see a need for the underlying XDR formats modifications. Everything is already working, we just need a trusted hosting and controlled source codes modification via pool requests. It won't require any code changes for existing SDF-maintained projects.

                      OrbitLens Now I'm a bit perplex. You said you didn't want to multiply standards but I can tell your transaction request is neither using cosmic link protocol nor sep-0007. It's nearly using it, but there's a few details that doesn't seems to bring anything except making it different. You're considering making it into another SEP. Then I wonder what's the point of SEP if each one is doing its own?

                        OrbitLens According to <https://stellar.github.io/js-stellar-sdk/Transaction.html>, it is the hash of the buffer you're mentioning that is actually signed, so if you sign the hash of input message, and if any binary value may be passed, it is exploitable.

                        Once again, when it is about login/authentication (automatic signing) I would prevent any kind of text input as it may have legal value in the future.