security: validate phone recipients (#144)
Co-authored-by: draix <draix@users.noreply.github.com>
This commit is contained in:
parent
54d44b34fc
commit
318421d415
@ -13,6 +13,7 @@
|
||||
### Security
|
||||
|
||||
- Auth: reject `?` and `#` in whatsmeow session store paths to avoid SQLite URI parameter injection. (#180 — thanks @shaun0927)
|
||||
- Send: validate phone-number recipients before constructing WhatsApp JIDs. (#144 — thanks @draix)
|
||||
- Store: restrict index and session SQLite database files to owner-only permissions. (#147 — thanks @draix)
|
||||
|
||||
### Fixed
|
||||
|
||||
@ -33,8 +33,17 @@ func TestParseUserOrJID(t *testing.T) {
|
||||
{name: "phone", input: "1234567890", wantUser: "1234567890", wantServer: types.DefaultUserServer},
|
||||
{name: "phone with plus", input: "+1234567890", wantUser: "1234567890", wantServer: types.DefaultUserServer},
|
||||
{name: "phone with spaces and plus", input: " +1234567890 ", wantUser: "1234567890", wantServer: types.DefaultUserServer},
|
||||
{name: "minimum length phone", input: "1234567", wantUser: "1234567", wantServer: types.DefaultUserServer},
|
||||
{name: "maximum length phone", input: "123456789012345", wantUser: "123456789012345", wantServer: types.DefaultUserServer},
|
||||
{name: "group jid", input: "123@g.us", wantUser: "123", wantServer: types.GroupServer},
|
||||
{name: "empty after plus", input: "+", wantErr: true},
|
||||
{name: "too short phone", input: "123456", wantErr: true},
|
||||
{name: "too long phone", input: "1234567890123456", wantErr: true},
|
||||
{name: "letters in phone", input: "123abc456", wantErr: true},
|
||||
{name: "punctuation in phone", input: "123-456-7890", wantErr: true},
|
||||
{name: "spaces inside phone", input: "123 456 7890", wantErr: true},
|
||||
{name: "plus inside phone", input: "12+34567", wantErr: true},
|
||||
{name: "double leading plus", input: "++1234567", wantErr: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@ -15,13 +15,29 @@ func ParseUserOrJID(s string) (types.JID, error) {
|
||||
if strings.Contains(s, "@") {
|
||||
return types.ParseJID(s)
|
||||
}
|
||||
s = strings.TrimPrefix(s, "+")
|
||||
if s == "" {
|
||||
return types.JID{}, fmt.Errorf("recipient is required")
|
||||
phone, err := normalizePhoneRecipient(s)
|
||||
if err != nil {
|
||||
return types.JID{}, err
|
||||
}
|
||||
return types.JID{User: s, Server: types.DefaultUserServer}, nil
|
||||
return types.JID{User: phone, Server: types.DefaultUserServer}, nil
|
||||
}
|
||||
|
||||
func IsGroupJID(jid types.JID) bool {
|
||||
return jid.Server == types.GroupServer
|
||||
}
|
||||
|
||||
func normalizePhoneRecipient(s string) (string, error) {
|
||||
phone := strings.TrimPrefix(s, "+")
|
||||
if phone == "" {
|
||||
return "", fmt.Errorf("recipient is required")
|
||||
}
|
||||
if len(phone) < 7 || len(phone) > 15 {
|
||||
return "", fmt.Errorf("invalid phone number %q: must be 7-15 digits", s)
|
||||
}
|
||||
for _, ch := range phone {
|
||||
if ch < '0' || ch > '9' {
|
||||
return "", fmt.Errorf("invalid phone number %q: must contain digits only", s)
|
||||
}
|
||||
}
|
||||
return phone, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user