diff --git a/go/enclave/storage/init/migration/db_migration.go b/go/enclave/storage/init/migration/db_migration.go index 3afc838487..b243bc0125 100644 --- a/go/enclave/storage/init/migration/db_migration.go +++ b/go/enclave/storage/init/migration/db_migration.go @@ -4,6 +4,7 @@ import ( "database/sql" "embed" "errors" + "fmt" "io/fs" "math/big" "sort" @@ -15,7 +16,7 @@ import ( "github.com/obscuronet/go-obscuro/go/enclave/storage/enclavedb" ) -const currentFileKey = "CURRENT_FILE" +const currentMigrationVersionKey = "CURRENT_MIGRATION_VERSION" func DBMigration(db *sql.DB, sqlFiles embed.FS, logger gethlog.Logger) error { migrationFiles, err := readMigrationFiles(sqlFiles) @@ -26,9 +27,9 @@ func DBMigration(db *sql.DB, sqlFiles embed.FS, logger gethlog.Logger) error { maxMigration := int64(len(migrationFiles)) var maxDB int64 - config, err := enclavedb.FetchConfig(db, currentFileKey) + config, err := enclavedb.FetchConfig(db, currentMigrationVersionKey) if err != nil { - // first time there is no entry, so we assume 001 was executed already + // first time there is no entry, so 001 was executed already ( triggered at launch/manifest time ) if errors.Is(err, errutil.ErrNotFound) { maxDB = 1 } else { @@ -47,7 +48,7 @@ func DBMigration(db *sql.DB, sqlFiles embed.FS, logger gethlog.Logger) error { } err = executeMigration(db, string(content), i) if err != nil { - return err + return fmt.Errorf("unable to execute migration for %s - %w", migrationFiles[i].Name(), err) } logger.Info("Successfully executed", "file", migrationFiles[i].Name(), "index", i) } @@ -65,7 +66,7 @@ func executeMigration(db *sql.DB, content string, migrationOrder int64) error { return err } - _, err = enclavedb.WriteConfigToTx(tx, currentFileKey, big.NewInt(migrationOrder).Bytes()) + _, err = enclavedb.WriteConfigToTx(tx, currentMigrationVersionKey, big.NewInt(migrationOrder).Bytes()) if err != nil { return err } diff --git a/tools/walletextension/api/routes.go b/tools/walletextension/api/routes.go index 2ef79d592f..df8cc091ea 100644 --- a/tools/walletextension/api/routes.go +++ b/tools/walletextension/api/routes.go @@ -156,8 +156,8 @@ func ethRequestHandler(walletExt *walletextension.WalletExtension, conn userconn return } - // Get userID and check if user exists (if not - use default user) - hexUserID, err := getQueryParameter(conn.ReadRequestParams(), common.UserQueryParameter) + // Get userID + hexUserID, err := getUserID(conn, 1) if err != nil || !walletExt.UserExists(hexUserID) { walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w. Using the default user", err).Error()) hexUserID = hex.EncodeToString([]byte(common.DefaultUser)) // todo (@ziga) - this can be removed once old WE endpoints are removed @@ -317,7 +317,7 @@ func authenticateRequestHandler(walletExt *walletextension.WalletExtension, user } // read userID from query params - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("Malformed query: 'u' required - representing userID") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) @@ -350,7 +350,7 @@ func queryRequestHandler(walletExt *walletextension.WalletExtension, userConn us return } - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("user ('u') not found in query parameters") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) @@ -362,6 +362,12 @@ func queryRequestHandler(walletExt *walletextension.WalletExtension, userConn us walletExt.Logger().Error(fmt.Errorf("address not found in the query params: %w", err).Error()) return } + // check if address length is correct + if len(address) != common.EthereumAddressLen { + userConn.HandleError(fmt.Sprintf("provided address length is %d, expected: %d", len(address), common.EthereumAddressLen)) + walletExt.Logger().Error(fmt.Errorf(fmt.Sprintf("provided address length is %d, expected: %d", len(address), common.EthereumAddressLen)).Error()) + return + } // check if this account is registered with given user found, err := walletExt.UserHasAccount(hexUserID, address) @@ -399,7 +405,7 @@ func revokeRequestHandler(walletExt *walletextension.WalletExtension, userConn u return } - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("user ('u') not found in query parameters") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) diff --git a/tools/walletextension/api/staticOG/javascript.js b/tools/walletextension/api/staticOG/javascript.js index f416ee5017..d48cf4fbd5 100644 --- a/tools/walletextension/api/staticOG/javascript.js +++ b/tools/walletextension/api/staticOG/javascript.js @@ -64,7 +64,7 @@ async function authenticateAccountWithObscuroGateway(ethereum, account, userID) return "Account is already authenticated" } - const textToSign = "Register " + userID + " for " + account; + const textToSign = "Register " + userID + " for " + account.toLowerCase(); const signature = await ethereum.request({ method: metamaskPersonalSign, params: [textToSign, account] diff --git a/tools/walletextension/api/utils.go b/tools/walletextension/api/utils.go index 8a8ef189bb..3bca5e921a 100644 --- a/tools/walletextension/api/utils.go +++ b/tools/walletextension/api/utils.go @@ -3,9 +3,11 @@ package api import ( "encoding/json" "fmt" + "strings" "github.com/obscuronet/go-obscuro/tools/walletextension/accountmanager" "github.com/obscuronet/go-obscuro/tools/walletextension/common" + "github.com/obscuronet/go-obscuro/tools/walletextension/userconn" ) func parseRequest(body []byte) (*accountmanager.RPCRequest, error) { @@ -46,3 +48,36 @@ func getQueryParameter(params map[string]string, selectedParameter string) (stri return value, nil } + +func getUserID(conn userconn.UserConn, userIDPosition int) (string, error) { + // try getting userID from query parameters and return it if successful + userID, err := getQueryParameter(conn.ReadRequestParams(), common.UserQueryParameter) + if err == nil { + if len(userID) != common.MessageUserIDLen { + return "", fmt.Errorf(fmt.Sprintf("wrong length of userID from URL. Got: %d, Expected: %d", len(userID), common.MessageUserIDLen)) + } + return userID, err + } + + // Alternatively, try to get it from URL path + // This is a temporary hack to work around hardhat bug which causes hardhat to ignore query parameters. + // It is unsafe because https encrypts query parameters, + // but not URL itself and will be removed once hardhat bug is resolved. + path := conn.GetHTTPRequest().URL.Path + path = strings.Trim(path, "/") + parts := strings.Split(path, "/") + + // our URLs, which require userID, have following pattern: // + // userID can be only on second or third position + if len(parts) != userIDPosition+1 { + return "", fmt.Errorf("URL structure of the request looks wrong") + } + userID = parts[userIDPosition] + + // Check if userID has the correct length + if len(userID) != common.MessageUserIDLen { + return "", fmt.Errorf(fmt.Sprintf("wrong length of userID from URL. Got: %d, Expected: %d", len(userID), common.MessageUserIDLen)) + } + + return userID, nil +} diff --git a/tools/walletextension/common/constants.go b/tools/walletextension/common/constants.go index 0d57916901..4243aea462 100644 --- a/tools/walletextension/common/constants.go +++ b/tools/walletextension/common/constants.go @@ -45,6 +45,7 @@ const ( MessageFormatRegex = `^Register\s(\w+)\sfor\s(\w+)$` MessageUserIDLen = 64 SignatureLen = 65 + EthereumAddressLen = 42 PersonalSignMessagePrefix = "\x19Ethereum Signed Message:\n%d%s" GetStorageAtUserIDRequestMethodName = "getUserID" SuccessMsg = "success" diff --git a/tools/walletextension/userconn/user_conn.go b/tools/walletextension/userconn/user_conn.go index 017f85c775..b40e0ed28e 100644 --- a/tools/walletextension/userconn/user_conn.go +++ b/tools/walletextension/userconn/user_conn.go @@ -31,6 +31,7 @@ type UserConn interface { HandleError(msg string) SupportsSubscriptions() bool IsClosed() bool + GetHTTPRequest() *http.Request } // Represents a user's connection over HTTP. @@ -106,6 +107,10 @@ func (h *userConnHTTP) ReadRequestParams() map[string]string { return getQueryParams(h.req.URL.Query()) } +func (h *userConnHTTP) GetHTTPRequest() *http.Request { + return h.req +} + func (w *userConnWS) ReadRequest() ([]byte, error) { _, msg, err := w.conn.ReadMessage() if err != nil { @@ -166,6 +171,10 @@ func (w *userConnWS) ReadRequestParams() map[string]string { return getQueryParams(w.req.URL.Query()) } +func (w *userConnWS) GetHTTPRequest() *http.Request { + return w.req +} + // Logs the error, prints it to the console, and returns the error over HTTP. func httpLogAndSendErr(resp http.ResponseWriter, msg string) { http.Error(resp, msg, httpCodeErr)