Skip to content

Commit a27492a

Browse files
sumnerevansclaude
andauthored
security: prevent email enumeration on teacher login (#200)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 63d4836 commit a27492a

3 files changed

Lines changed: 13 additions & 34 deletions

File tree

internal/teacherlogin.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,14 @@ func (a *Application) HandleTeacherLogin(w http.ResponseWriter, r *http.Request)
6161

6262
teacher, err := a.DB.GetTeacherByEmail(r.Context(), emailAddress)
6363
if err != nil {
64-
log.Warn().Err(err).Msg("failed to find teacher by email")
65-
a.TeacherLoginRenderer(w, r, map[string]any{
66-
"Email": emailAddress,
67-
"EmailNotFound": true,
68-
})
64+
log.Warn().Err(err).Msg("failed to find teacher by email, redirecting without sending email")
65+
http.SetCookie(w, &http.Cookie{Name: "email", Value: emailAddress, Path: "/", HttpOnly: true, SameSite: http.SameSiteLaxMode})
66+
http.Redirect(w, r, "/register/teacher/emaillogin", http.StatusSeeOther)
6967
return
7068
} else if !teacher.EmailConfirmed {
71-
log.Warn().Err(err).Msg("teacher email not confirmed, not sending login code to avoid amplification attacks")
72-
a.TeacherLoginRenderer(w, r, map[string]any{
73-
"Email": emailAddress,
74-
"EmailNotConfirmed": true,
75-
})
69+
log.Warn().Msg("teacher email not confirmed, redirecting without sending email")
70+
http.SetCookie(w, &http.Cookie{Name: "email", Value: emailAddress, Path: "/", HttpOnly: true, SameSite: http.SameSiteLaxMode})
71+
http.Redirect(w, r, "/register/teacher/emaillogin", http.StatusSeeOther)
7672
return
7773
}
7874

website/templates/emaillogin.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ <h1>Email Login</h1>
2525
<div class="row">
2626
<div class="col m-4 text-center">
2727
<p>
28-
We've sent an email to <b>{{ .Data.Email }}</b>.
28+
If <b>{{ .Data.Email }}</b> has a confirmed account, we've sent a login link to that address.
2929
</p>
3030
<p style="font-size: 10em; line-height: 0;"><i class="fa fa-envelope-o"></i></p>
3131
<p>
32-
Please check your email and click the link to log in.
32+
Please check your email and click the link to log in. If you haven't confirmed your email
33+
yet, check your inbox for the original confirmation email. Need help?
34+
<a href="mailto:support@mineshspc.com">Contact support</a>.
3335
</p>
3436
</div>
3537
</div>

website/templates/teacherlogin.html

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,9 @@ <h1>Login to Teacher Account</h1>
1515
<form method="post" action="/register/teacher/login" class="form-floating">
1616
<div class="row">
1717
<div class="col m-4 mb-0">
18-
{{ with .Data.EmailNotFound }}
19-
<div class="alert alert-danger" role="alert">
20-
That email doesn't exist in our system. Did you want to
21-
<a href="/register/teacher/createaccount">create an account</a> instead?
22-
</div>
23-
{{ else }}
24-
{{ with .Data.EmailNotConfirmed }}
25-
<div class="alert alert-danger" role="alert">
26-
<p>
27-
That email hasn't been confirmed yet. Please confirm your email before logging in.
28-
</p>
29-
<p>
30-
Lost your confirmation email? Send an email to
31-
<a href="mailto:support@mineshspc.com">support@mineshspc.com</a>.
32-
</p>
33-
</div>
34-
{{ else }}
35-
<div class="alert alert-secondary" role="alert">
36-
Don't have an account? <a href="/register/teacher/createaccount">Create an account</a> instead.
37-
</div>
38-
{{ end }}
39-
{{ end }}
18+
<div class="alert alert-secondary" role="alert">
19+
Don't have an account? <a href="/register/teacher/createaccount">Create an account</a> instead.
20+
</div>
4021
</div>
4122
</div>
4223
<div class="row">

0 commit comments

Comments
 (0)