fix(security): escape LDAP attribute data in HTML output to prevent XSS (CWE-79)
Use html.EscapeString for attribute names and values when building HTML. Move dynamic data (alias URL, API token) to data-* attributes and use a self-contained onclick function to read them, eliminating JS string injection via LDAP-controlled values. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
57775bbf89
commit
93673510d8
1 changed files with 13 additions and 4 deletions
17
login.go
17
login.go
|
|
@ -2,9 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
|
|
@ -55,16 +57,23 @@ func tryLogin(w http.ResponseWriter, r *http.Request) {
|
|||
cnt := "<ul>"
|
||||
for _, e := range entries {
|
||||
for i, v := range e.Values {
|
||||
safeName := html.EscapeString(e.Name)
|
||||
safeVal := html.EscapeString(v)
|
||||
elemID := fmt.Sprintf("mailAlias-%d", i)
|
||||
if e.Name == "userPassword" || e.Name == "krbPrincipalKey" {
|
||||
cnt += "<li><strong>" + e.Name + ":</strong> <em>[...]</em></li>"
|
||||
cnt += "<li><strong>" + safeName + ":</strong> <em>[...]</em></li>"
|
||||
} else if e.Name == "mailAlias" && len(strings.SplitN(v, "@", 2)[0]) == 10 {
|
||||
cnt += "<li id='" + fmt.Sprintf("mailAlias-%d", i) + "'><strong>" + e.Name + ":</strong> " + v + `<button type="button" class="mx-1 btn btn-sm btn-danger" onclick="fetch('/api/v1/aliases/` + v + `', {'method': 'delete', 'headers': {'Authorization': 'Bearer ` + apiToken + `'}}).then((res) => { if (res.ok) document.getElementById('` + fmt.Sprintf("mailAlias-%d", i) + `').remove(); });">Supprimer</a></li>`
|
||||
safeURL := url.PathEscape(v)
|
||||
safeToken := html.EscapeString(apiToken)
|
||||
safeElemID := html.EscapeString(elemID)
|
||||
cnt += `<li id="` + safeElemID + `"><strong>` + safeName + `:</strong> ` + safeVal +
|
||||
`<button type="button" class="mx-1 btn btn-sm btn-danger" data-alias="` + safeURL + `" data-token="` + safeToken + `" data-elem="` + safeElemID + `" onclick="(function(b){fetch('/api/v1/aliases/'+b.dataset.alias,{'method':'delete','headers':{'Authorization':'Bearer '+b.dataset.token}}).then(function(r){if(r.ok)document.getElementById(b.dataset.elem).remove();})})(this)">Supprimer</button></li>`
|
||||
} else {
|
||||
cnt += "<li><strong>" + e.Name + ":</strong> " + v + "</li>"
|
||||
cnt += "<li><strong>" + safeName + ":</strong> " + safeVal + "</li>"
|
||||
}
|
||||
}
|
||||
}
|
||||
displayTmpl(w, "message.html", map[string]interface{}{"details": template.HTML(`Login ok<br><br>Here are the information we have about you:` + cnt + "</ul><p>To use our Addy.io compatible API, use the following token: <code>" + apiToken + "</code></p>")})
|
||||
displayTmpl(w, "message.html", map[string]interface{}{"details": template.HTML(`Login ok<br><br>Here are the information we have about you:` + cnt + "</ul><p>To use our Addy.io compatible API, use the following token: <code>" + html.EscapeString(apiToken) + "</code></p>")})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue