commit 42c2a6856591e5dca5d9dde8a150b13070394fd5
parent b155150004b3ae3bef58f6d3096f8c4d91d6a72e
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date: Mon, 18 Mar 2024 21:32:09 +0100
Sanitize user inputs.
Diffstat:
1 file changed, 34 insertions(+), 29 deletions(-)
diff --git a/pkg/rest/gnsregistrar.go b/pkg/rest/gnsregistrar.go
@@ -27,6 +27,7 @@ import (
"html/template"
"io"
"net/http"
+ "net/url"
"os"
"os/exec"
"strings"
@@ -275,7 +276,7 @@ func (t *Registrar) searchPage(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, fmt.Sprintf("/?error=%s", err), http.StatusSeeOther)
return
}
- http.Redirect(w, r, "/name/" + label, http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + url.QueryEscape(label), http.StatusSeeOther)
return
}
@@ -389,9 +390,10 @@ func (t *Registrar) updateRegistration(w http.ResponseWriter, r *http.Request) {
zkey string
)
vars := mux.Vars(r)
+ sanitizedLabel := url.QueryEscape(vars["label"])
w.Header().Set("Content-Type", "text/html; charset=utf-8")
client = &http.Client{}
- req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + vars["label"] + "?include_maintenance=yes", nil)
+ req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + sanitizedLabel + "?include_maintenance=yes", nil)
if t.GnunetBasicAuthEnabled {
req.SetBasicAuth(t.GnunetUsername, t.GnunetPassword)
}
@@ -422,23 +424,23 @@ func (t *Registrar) updateRegistration(w http.ResponseWriter, r *http.Request) {
return
}
} else if http.StatusNotFound != resp.StatusCode {
- http.Redirect(w, r, "/name/" + vars["label"] + "?error=Error determining zone status", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Error determining zone status", http.StatusSeeOther)
return
}
if nil == regMetadata {
- http.Redirect(w, r, "/name/"+vars["label"], http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel, http.StatusSeeOther)
return
}
err = r.ParseForm()
if nil != err {
fmt.Printf("Unable to parse form: " + err.Error())
- http.Redirect(w, r, "/name/"+vars["label"] + "?error=Form invalid", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Form invalid", http.StatusSeeOther)
return
}
token = r.Form.Get("token")
zkey = r.Form.Get("zkey")
if regMetadata.RegistrationID != token {
- http.Redirect(w, r, "/name/"+vars["label"] + "?error=Unauthorized", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Unauthorized", http.StatusSeeOther)
return
}
for _, record := range namestoreResponse.Records {
@@ -454,10 +456,10 @@ func (t *Registrar) updateRegistration(w http.ResponseWriter, r *http.Request) {
err = t.createOrUpdateRegistration(&namestoreResponse)
if nil != err {
fmt.Println(err)
- http.Redirect(w, r, "/name/"+vars["label"] + "?error=Update: Internal error", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Update: Internal error", http.StatusSeeOther)
return
}
- http.Redirect(w, r, "/name/"+vars["label"] + "/edit?token=" + token, http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "/edit?token=" + token, http.StatusSeeOther)
return
}
@@ -469,9 +471,10 @@ func (t *Registrar) editRegistration(w http.ResponseWriter, r *http.Request) {
client *http.Client
)
vars := mux.Vars(r)
+ sanitizedLabel := url.QueryEscape(vars["label"])
w.Header().Set("Content-Type", "text/html; charset=utf-8")
client = &http.Client{}
- req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + vars["label"] + "?include_maintenance=yes", nil)
+ req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + sanitizedLabel + "?include_maintenance=yes", nil)
if t.GnunetBasicAuthEnabled {
req.SetBasicAuth(t.GnunetUsername, t.GnunetPassword)
}
@@ -502,15 +505,15 @@ func (t *Registrar) editRegistration(w http.ResponseWriter, r *http.Request) {
return
}
} else if http.StatusNotFound != resp.StatusCode {
- http.Redirect(w, r, "/name/" + vars["label"] + "?error=Error determining zone status", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Error determining zone status", http.StatusSeeOther)
return
}
if nil == regMetadata {
- http.Redirect(w, r, "/name/"+vars["label"], http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel, http.StatusSeeOther)
return
}
if regMetadata.RegistrationID != r.URL.Query().Get("token") {
- http.Redirect(w, r, "/name/"+vars["label"] + "?error=Unauthorized", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Unauthorized", http.StatusSeeOther)
return
}
for _, record := range namestoreResponse.Records {
@@ -555,12 +558,13 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
client = &http.Client{}
label = vars["label"]
+ sanitizedLabel := url.QueryEscape(vars["label"])
err := t.isNameValid(label)
if nil != err {
http.Redirect(w, r, fmt.Sprintf("/?error=%s", err), http.StatusSeeOther)
return
}
- req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + label + "?include_maintenance=yes", nil)
+ req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + sanitizedLabel + "?include_maintenance=yes", nil)
if t.GnunetBasicAuthEnabled {
req.SetBasicAuth(t.GnunetUsername, t.GnunetPassword)
}
@@ -584,19 +588,19 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Failed to get zone contents" + err.Error())
return
}
- regMetadata, err = t.getCurrentRegistrationMetadata(label, &namestoreResponse)
+ regMetadata, err = t.getCurrentRegistrationMetadata(sanitizedLabel, &namestoreResponse)
if err != nil {
http.Redirect(w, r, "/" + "?error=Registration failed: Failed to get registration metadata", http.StatusSeeOther)
fmt.Printf("Failed to get registration metadata" + err.Error())
return
}
} else if http.StatusNotFound != resp.StatusCode {
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Error determining zone status", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Error determining zone status", http.StatusSeeOther)
return
}
if nil != regMetadata {
if regMetadata.Paid == false {
- http.Redirect(w, r, "/name/"+ label + "?error=Registration failed: Pending buy order", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Pending buy order", http.StatusSeeOther)
return
}
regMetadata.Paid = false
@@ -605,20 +609,20 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
regId = generateRegistrationId()
}
summaryMsg := strings.Replace(t.SummaryTemplateString, "${NAME}", label, 1)
- orderID, newOrderErr := t.Merchant.AddNewOrder(*t.RegistrationCost, summaryMsg, t.BaseUrl + "/name/" + label + "/edit?token=" + regId)
+ orderID, newOrderErr := t.Merchant.AddNewOrder(*t.RegistrationCost, summaryMsg, t.BaseUrl + "/name/" + sanitizedLabel + "/edit?token=" + regId)
if newOrderErr != nil {
fmt.Println(newOrderErr)
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Unable to create order", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Unable to create order", http.StatusSeeOther)
return
}
_, payto, paytoErr := t.Merchant.IsOrderPaid(orderID)
if paytoErr != nil {
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Error getting payment data", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Error getting payment data", http.StatusSeeOther)
return
}
qrPng, qrErr := qrcode.Encode(payto, qrcode.Medium, 256)
if qrErr != nil {
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Error generating QR code", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Error generating QR code", http.StatusSeeOther)
return
}
paymentUntil := time.Now().Add(t.PaymentExpiration)
@@ -638,7 +642,7 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
metadataRecordValue, err := json.Marshal(regMetadata)
if nil != err {
fmt.Println(err)
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Internal error", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Internal error", http.StatusSeeOther)
return
}
metaRecord.Value = string(metadataRecordValue)
@@ -646,14 +650,14 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
err = t.createOrUpdateRegistration(&namestoreResponse)
if nil != err {
fmt.Println(err)
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Internal error", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Internal error", http.StatusSeeOther)
return
}
} else {
- err = t.setupRegistrationMetadataBeforePayment(label, r.URL.Query().Get("zkey"), orderID, paymentUntil, regId)
+ err = t.setupRegistrationMetadataBeforePayment(sanitizedLabel, r.URL.Query().Get("zkey"), orderID, paymentUntil, regId)
if err != nil {
fmt.Println(err)
- http.Redirect(w, r, "/name/" + label + "?error=Registration failed: Internal error", http.StatusSeeOther)
+ http.Redirect(w, r, "/name/" + sanitizedLabel + "?error=Registration failed: Internal error", http.StatusSeeOther)
return
}
}
@@ -662,9 +666,9 @@ func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) {
fullData := map[string]interface{}{
"qrCode": template.URL("data:image/png;base64," + encodedPng),
"payto": template.URL(payto),
- "fulfillmentUrl": template.URL(t.BaseUrl + "/name/" + label + "/edit?token=" + regId),
+ "fulfillmentUrl": template.URL(t.BaseUrl + "/name/" + sanitizedLabel + "/edit?token=" + regId),
"registrationId": regId,
- "label": label,
+ "label": sanitizedLabel,
"error": errorMsg,
"cost": cost,
"suffixHint": t.SuffixHint,
@@ -795,12 +799,13 @@ func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
label := vars["label"]
err := t.isNameValid(label)
+ sanitizedLabel := url.QueryEscape(vars["label"])
if nil != err {
http.Redirect(w, r, fmt.Sprintf("/?error=%s", err), http.StatusSeeOther)
return
}
client = &http.Client{}
- req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + label + "?include_maintenance=yes", nil)
+ req, _ := http.NewRequest(http.MethodGet,t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + sanitizedLabel + "?include_maintenance=yes", nil)
if t.GnunetBasicAuthEnabled {
req.SetBasicAuth(t.GnunetUsername, t.GnunetPassword)
}
@@ -824,7 +829,7 @@ func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/" + "?error=Failed to get zone contents.", http.StatusSeeOther)
return
}
- regMetadata, err = t.getCurrentRegistrationMetadata(label, &namestoreResponse)
+ regMetadata, err = t.getCurrentRegistrationMetadata(sanitizedLabel, &namestoreResponse)
if err != nil {
fmt.Println("Failed to get registration metadata: " + err.Error())
http.Redirect(w, r, "/" + "?error=Failed to get registration metadata.", http.StatusSeeOther)
@@ -848,7 +853,7 @@ func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) {
}
cost, _ := t.RegistrationCost.FormatWithCurrencySpecification(t.CurrencySpec)
fullData := map[string]interface{}{
- "label": label,
+ "label": sanitizedLabel,
"error": r.URL.Query().Get("error"),
"cost": cost,
"available": regMetadata == nil,