任何调用者都能先占用他人的邮箱并将其关联到自己的身份
原文依据:3 处注册接口接受调用者提供的任意邮箱,在证明邮箱所有权之前就创建调用者与邮箱的关联、占用唯一性记录并加入营销主题。之后才发送验证邮件。
攻击者可用受害者邮箱注册,使真正持有人因“Email already taken”而无法注册。若持有人点击收到的验证链接,该邮箱还可能被验证为攻击者主体所建资料的邮箱,并启用该资料的营销投递资格。
注册接口在验证邮箱归属前,就把调用者提供的任意邮箱写入其个人资料和全局唯一集合。其他人随后使用该邮箱会收到“Email already taken”。因此,只要此示例被实际采用,调用者就可能抢占他人的邮箱并阻止真实所有者注册;后续发送验证邮件并不会撤销已建立的关联。用户可要求作者在验证成功前不要永久占用邮箱,并限制未验证记录的权限和有效期。
public shared ({ caller }) func registerUser(name : Text, email : Text) : async () { // Check if the user already exists if (userProfiles.containsKey(caller)) { Runtime.trap("User already registered"); }; // Check if the email is already used if (emails.contains(email)) { Runtime.trap("Email already taken"); }; // Add a user record userProfiles.add( caller, { name; email; }, ); emails.add(email); // Subscribe the user to the Newsletter topic by default查看另外 2 个位置
emails.add(email); // Subscribe the user to the Newsletter topic by default let topicId = EmailSubscribers.getTopicId(emailSubscribers, newsletterTopic) ?? Runtime.trap("Newsletter topic not found"); ignore EmailSubscribers.add(emailSubscribers, topicId, email); // Send a verification email let result = await EmailClient.sendVerificationEmail( "no-reply", [email], "Welcome to Our Service", "Hello " # name # ",<br><br>Thank you for registering with our service.<br><br>Please <a href=\"{{VERIFICATION_URL}}\">click here</a> to verify your email address.<br><br>By clicking on the verification link you also agree to sign-up to the monthly Newsletter which you can unsubscribe from at any time.<br><br>Best regards,<br>The Team", ); ignore EmailSubscribers.add(emailSubscribers, topicId, email); // Send a verification email let result = await EmailClient.sendVerificationEmail( "no-reply", [email], "Welcome to Our Service", "Hello " # name # ",<br><br>Thank you for registering with our service.<br><br>Please <a href=\"{{VERIFICATION_URL}}\">click here</a> to verify your email address.<br><br>By clicking on the verification link you also agree to sign-up to the monthly Newsletter which you can unsubscribe from at any time.<br><br>Best regards,<br>The Team", );