优化入站邮件禁用账号过滤与POP3越权防范
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-05 08:29:27 +08:00
parent faf06fc3b1
commit 8621bb2670
3 changed files with 31 additions and 2 deletions

View File

@ -144,6 +144,10 @@ func (a action) Uidl(session *gopop.Session, msg string) ([]gopop.UidlItem, erro
reqId := cast.ToInt64(msg)
if reqId > 0 {
info, err := detail.GetEmailDetail(session.Ctx.(*context.Context), cast.ToInt(reqId), false)
if err != nil || info == nil {
return nil, errors2.New("no such message")
}
log.WithContext(session.Ctx).Debugf("Uidl \n %+v", reqId)
return []gopop.UidlItem{
{

View File

@ -72,3 +72,28 @@ func TestActionUserPreservesFullEmailIdentifier(t *testing.T) {
t.Fatalf("POP3 user identifier = %q, want full email identifier", session.User)
}
}
func TestActionUidlOwnershipValidation(t *testing.T) {
testRoot := t.TempDir()
config.Instance = &config.Config{DbType: config.DBTypeSQLite, DbDSN: filepath.Join(testRoot, "pop3_uidl.db")}
if err := db.Init(""); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if db.Instance != nil {
_ = db.Instance.Close()
}
})
a := action{}
session := &gopop.Session{
Ctx: &context.Context{
UserID: 1,
},
}
// 查询未授权/不存在的邮件 ID 应返回错误
_, err := a.Uidl(session, "99999")
if err == nil {
t.Fatal("expected error for unauthorized/non-existent message UIDL query, got nil")
}
}

View File

@ -153,7 +153,7 @@ func resolveIncomingUsers(ctx *context.Context, email *parsemail.Email, emailTyp
accounts := incomingAccounts(email, reallyTo)
var users []*models.User
if len(accounts) > 0 {
where, params, err := builder.ToSQL(builder.In("LOWER(account)", accounts))
where, params, err := builder.ToSQL(builder.And(builder.In("LOWER(account)", accounts), builder.Eq{"disabled": 0}))
if err != nil {
return nil, false, err
}
@ -175,7 +175,7 @@ func resolveIncomingUsers(ctx *context.Context, email *parsemail.Email, emailTyp
}
log.WithContext(ctx).Infof("收件人不存在但DKIM验证通过,转交管理员: recipient_count=%d", len(accounts))
if err := db.Instance.Table(&models.User{}).Where("is_admin=1").Find(&users); err != nil {
if err := db.Instance.Table(&models.User{}).Where("is_admin=1 AND disabled=0").Find(&users); err != nil {
return nil, false, err
}
if len(users) == 0 {