mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-04-23 03:00:50 -04:00
feat(coordinator): fix login replay attack (#723)
Co-authored-by: Péter Garamvölgyi <peter@scroll.io> Co-authored-by: colinlyguo <colinlyguo@scroll.io>
This commit is contained in:
@@ -5,7 +5,7 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tag = "v4.1.0"
|
var tag = "v4.1.1"
|
||||||
|
|
||||||
var commit = func() string {
|
var commit = func() string {
|
||||||
if info, ok := debug.ReadBuildInfo(); ok {
|
if info, ok := debug.ReadBuildInfo(); ok {
|
||||||
|
|||||||
@@ -81,9 +81,11 @@ func (c *CoordinatorApp) MockConfig(store bool) error {
|
|||||||
}
|
}
|
||||||
// Reset prover manager config for manager test cases.
|
// Reset prover manager config for manager test cases.
|
||||||
cfg.ProverManager = &coordinatorConfig.ProverManager{
|
cfg.ProverManager = &coordinatorConfig.ProverManager{
|
||||||
ProversPerSession: 1,
|
ProversPerSession: 1,
|
||||||
Verifier: &coordinatorConfig.VerifierConfig{MockMode: true},
|
Verifier: &coordinatorConfig.VerifierConfig{MockMode: true},
|
||||||
CollectionTimeSec: 60,
|
CollectionTimeSec: 60,
|
||||||
|
SessionAttempts: 10,
|
||||||
|
MaxVerifierWorkers: 4,
|
||||||
}
|
}
|
||||||
cfg.DB.DSN = base.DBImg.Endpoint()
|
cfg.DB.DSN = base.DBImg.Endpoint()
|
||||||
cfg.L2.ChainID = 111
|
cfg.L2.ChainID = 111
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"prover_manager": {
|
"prover_manager": {
|
||||||
"provers_per_session": 1,
|
"provers_per_session": 1,
|
||||||
"session_attempts": 2,
|
"session_attempts": 5,
|
||||||
"collection_time_sec": 180,
|
"collection_time_sec": 180,
|
||||||
"verifier": {
|
"verifier": {
|
||||||
"mock_mode": true,
|
"mock_mode": true,
|
||||||
"params_path": "",
|
"params_path": "",
|
||||||
"assets_path": ""
|
"assets_path": ""
|
||||||
},
|
},
|
||||||
"max_verifier_workers": 10
|
"max_verifier_workers": 4
|
||||||
},
|
},
|
||||||
"db": {
|
"db": {
|
||||||
"driver_name": "postgres",
|
"driver_name": "postgres",
|
||||||
@@ -22,6 +22,6 @@
|
|||||||
"auth": {
|
"auth": {
|
||||||
"secret": "prover secret key",
|
"secret": "prover secret key",
|
||||||
"challenge_expire_duration_sec": 3600,
|
"challenge_expire_duration_sec": 3600,
|
||||||
"login_expire_duration_sec": 3600
|
"login_expire_duration_sec": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,24 +8,19 @@ import (
|
|||||||
"scroll-tech/common/database"
|
"scroll-tech/common/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
defaultNumberOfVerifierWorkers = 10
|
|
||||||
defaultNumberOfSessionRetryAttempts = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProverManager loads sequencer configuration items.
|
// ProverManager loads sequencer configuration items.
|
||||||
type ProverManager struct {
|
type ProverManager struct {
|
||||||
// The amount of provers to pick per proof generation session.
|
// The amount of provers to pick per proof generation session.
|
||||||
ProversPerSession uint8 `json:"provers_per_session"`
|
ProversPerSession uint8 `json:"provers_per_session"`
|
||||||
// Number of attempts that a session can be retried if previous attempts failed.
|
// Number of attempts that a session can be retried if previous attempts failed.
|
||||||
// Currently we only consider proving timeout as failure here.
|
// Currently we only consider proving timeout as failure here.
|
||||||
SessionAttempts uint8 `json:"session_attempts,omitempty"`
|
SessionAttempts uint8 `json:"session_attempts"`
|
||||||
// Zk verifier config.
|
// Zk verifier config.
|
||||||
Verifier *VerifierConfig `json:"verifier,omitempty"`
|
Verifier *VerifierConfig `json:"verifier"`
|
||||||
// Proof collection time (in seconds).
|
// Proof collection time (in seconds).
|
||||||
CollectionTimeSec int `json:"collection_time_sec"`
|
CollectionTimeSec int `json:"collection_time_sec"`
|
||||||
// Max number of workers in verifier worker pool
|
// Max number of workers in verifier worker pool
|
||||||
MaxVerifierWorkers int `json:"max_verifier_workers,omitempty"`
|
MaxVerifierWorkers int `json:"max_verifier_workers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// L2 loads l2geth configuration items.
|
// L2 loads l2geth configuration items.
|
||||||
@@ -38,7 +33,7 @@ type L2 struct {
|
|||||||
type Auth struct {
|
type Auth struct {
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
ChallengeExpireDurationSec int `json:"challenge_expire_duration_sec"`
|
ChallengeExpireDurationSec int `json:"challenge_expire_duration_sec"`
|
||||||
LoginExpireDurationSec int `json:"token_expire_duration_sec"` // unit: seconds
|
LoginExpireDurationSec int `json:"token_expire_duration_sec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config load configuration items.
|
// Config load configuration items.
|
||||||
@@ -69,12 +64,5 @@ func NewConfig(file string) (*Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.ProverManager.MaxVerifierWorkers == 0 {
|
|
||||||
cfg.ProverManager.MaxVerifierWorkers = defaultNumberOfVerifierWorkers
|
|
||||||
}
|
|
||||||
if cfg.ProverManager.SessionAttempts == 0 {
|
|
||||||
cfg.ProverManager.SessionAttempts = defaultNumberOfSessionRetryAttempts
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ func TestConfig(t *testing.T) {
|
|||||||
configTemplate := `{
|
configTemplate := `{
|
||||||
"prover_manager": {
|
"prover_manager": {
|
||||||
"provers_per_session": 1,
|
"provers_per_session": 1,
|
||||||
"session_attempts": %d,
|
"session_attempts": 5,
|
||||||
"collection_time_sec": 180,
|
"collection_time_sec": 180,
|
||||||
"verifier": {
|
"verifier": {
|
||||||
"mock_mode": true,
|
"mock_mode": true,
|
||||||
"params_path": "",
|
"params_path": "",
|
||||||
"agg_vk_path": ""
|
"agg_vk_path": ""
|
||||||
},
|
},
|
||||||
"max_verifier_workers": %d
|
"max_verifier_workers": 4
|
||||||
},
|
},
|
||||||
"db": {
|
"db": {
|
||||||
"driver_name": "postgres",
|
"driver_name": "postgres",
|
||||||
@@ -46,8 +46,7 @@ func TestConfig(t *testing.T) {
|
|||||||
assert.NoError(t, tmpFile.Close())
|
assert.NoError(t, tmpFile.Close())
|
||||||
assert.NoError(t, os.Remove(tmpFile.Name()))
|
assert.NoError(t, os.Remove(tmpFile.Name()))
|
||||||
}()
|
}()
|
||||||
config := fmt.Sprintf(configTemplate, defaultNumberOfSessionRetryAttempts, defaultNumberOfVerifierWorkers)
|
_, err = tmpFile.WriteString(configTemplate)
|
||||||
_, err = tmpFile.WriteString(config)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
cfg, err := NewConfig(tmpFile.Name())
|
cfg, err := NewConfig(tmpFile.Name())
|
||||||
@@ -88,36 +87,4 @@ func TestConfig(t *testing.T) {
|
|||||||
_, err = NewConfig(tmpFile.Name())
|
_, err = NewConfig(tmpFile.Name())
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Default MaxVerifierWorkers", func(t *testing.T) {
|
|
||||||
tmpFile, err := os.CreateTemp("", "example")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer func() {
|
|
||||||
assert.NoError(t, tmpFile.Close())
|
|
||||||
assert.NoError(t, os.Remove(tmpFile.Name()))
|
|
||||||
}()
|
|
||||||
config := fmt.Sprintf(configTemplate, defaultNumberOfSessionRetryAttempts, 0)
|
|
||||||
_, err = tmpFile.WriteString(config)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
cfg, err := NewConfig(tmpFile.Name())
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, defaultNumberOfVerifierWorkers, cfg.ProverManager.MaxVerifierWorkers)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Default SessionAttempts", func(t *testing.T) {
|
|
||||||
tmpFile, err := os.CreateTemp("", "example")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer func() {
|
|
||||||
assert.NoError(t, tmpFile.Close())
|
|
||||||
assert.NoError(t, os.Remove(tmpFile.Name()))
|
|
||||||
}()
|
|
||||||
config := fmt.Sprintf(configTemplate, 0, defaultNumberOfVerifierWorkers)
|
|
||||||
_, err = tmpFile.WriteString(config)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
cfg, err := NewConfig(tmpFile.Name())
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, uint8(defaultNumberOfSessionRetryAttempts), cfg.ProverManager.SessionAttempts)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,16 @@ func (a *AuthController) Login(c *gin.Context) (interface{}, error) {
|
|||||||
if err := c.ShouldBind(&login); err != nil {
|
if err := c.ShouldBind(&login); err != nil {
|
||||||
return "", fmt.Errorf("missing the public_key, err:%w", err)
|
return "", fmt.Errorf("missing the public_key, err:%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check login parameter's token is equal to bearer token, the Authorization must be existed
|
||||||
|
// if not exist, the jwt token will intercept it
|
||||||
|
brearToken := c.GetHeader("Authorization")
|
||||||
|
if brearToken != "Bearer "+login.Message.Challenge {
|
||||||
|
return "", fmt.Errorf("check challenge failure for the not equal challenge string")
|
||||||
|
}
|
||||||
|
|
||||||
// check the challenge is used, if used, return failure
|
// check the challenge is used, if used, return failure
|
||||||
if err := a.loginLogic.InsertChallengeString(c, login.Signature); err != nil {
|
if err := a.loginLogic.InsertChallengeString(c, login.Message.Challenge); err != nil {
|
||||||
return "", fmt.Errorf("login insert challenge string failure:%w", err)
|
return "", fmt.Errorf("login insert challenge string failure:%w", err)
|
||||||
}
|
}
|
||||||
return login, nil
|
return login, nil
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ func NewLoginLogic(db *gorm.DB) *LoginLogic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InsertChallengeString insert and check the challenge string is existed
|
// InsertChallengeString insert and check the challenge string is existed
|
||||||
func (l *LoginLogic) InsertChallengeString(ctx *gin.Context, signature string) error {
|
func (l *LoginLogic) InsertChallengeString(ctx *gin.Context, challenge string) error {
|
||||||
return l.challengeOrm.InsertChallenge(ctx, signature)
|
return l.challengeOrm.InsertChallenge(ctx, challenge)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user