-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version go1.15.7 windows/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\User\AppData\Local\go-build set GOENV=C:\Users\User\AppData\Roaming\go\env set GOEXE=.exe set GOFLAGS= set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOINSECURE= set GOMODCACHE=C:\Users\User\go\pkg\mod set GONOPROXY= set GONOSUMDB= set GOOS=windows set GOPATH=C:\Users\User\go set GOPRIVATE= set GOPROXY=https://proxy.golang.org,direct set GOROOT=c:\go set GOSUMDB=sum.golang.org set GOTMPDIR= set GOTOOLDIR=c:\go\pkg\tool\windows_amd64 set GCCGO=gccgo set AR=ar set CC=gcc set CXX=g++ set CGO_ENABLED=1 set GOMOD= set CGO_CFLAGS=-g -O2 set CGO_CPPFLAGS= set CGO_CXXFLAGS=-g -O2 set CGO_FFLAGS=-g -O2 set CGO_LDFLAGS=-g -O2 set PKG_CONFIG=pkg-config set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\User\AppData\Local\Temp\go-build809586734=/tmp/go-build -gno-record-gcc-switches
What did you do?
I try to utilize Microsoft's Graph API.
What I experienced was the password which I need to get a JWT in below post request fails
https://login.microsoftonline.com/{{TenantID}}/oauth2/v2.0/token
package main
import (
"fmt"
"net/url"
)
func main() {
password := "my!pass*w'-ith(and)%[]"
fmt.Println("Password : " + password)
fmt.Println("Password QueryEscape : " + url.QueryEscape(password))
fmt.Println("Password PathEscape : " + url.PathEscape(password))
fmt.Println("Expected Output : my!pass*w'-ith(and)%25%5B%5D")
}
Output :
$ go run main.go
Password : my!pass*w'-ith(and)%[]
Password QueryEscape : my%21pass%2Aw%27-ith%28and%29%25%5B%5D
Password PathEscape : my%21pass%2Aw%27-ith%28and%29%25%5B%5D
Expected Output : my!pass*w'-ith(and)%25%5B%5D
My experience with postman can get the token without any issue.
But when I do the same in Go Native I face the issue since we need to encode the password to generate x-www-form-urlencode. I believe this happens because Go is strict rfc-3986 compliance. But this could lead to many of the API Services built with JS will fail to communicate with Go applications since they use encodeURIComponent()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
Posman Screenshot :
What did you expect to see?
Expected Output : my!pass*w'-ith(and)%25%5B%5D
What did you see instead?
Password QueryEscape : my%21pass%2Aw%27-ith%28and%29%25%5B%5D
Password PathEscape : my%21pass%2Aw%27-ith%28and%29%25%5B%5D
I used below method to fix the issue.
Expect feedback and if this is accurate, also a fix in code.
package main
import (
"fmt"
"net/url"
"strings"
)
func main() {
password := "my!pass*w'-ith(and)%[]"
fmt.Println("Password : " + password)
fmt.Println("Password QueryEscape: " + url.QueryEscape(password))
fmt.Println("Password PathEscape: " + url.PathEscape(password))
encoded_pass := url.QueryEscape(password)
encoded_pass = strings.ReplaceAll(encoded_pass, "%21", "!")
encoded_pass = strings.ReplaceAll(encoded_pass, "%2A", "*")
encoded_pass = strings.ReplaceAll(encoded_pass, "%27", "'")
encoded_pass = strings.ReplaceAll(encoded_pass, "%28", "(")
encoded_pass = strings.ReplaceAll(encoded_pass, "%29", ")")
fmt.Println("Password Correct RFC Escape : " + encoded_pass)
}
Output :
Password : my!pass*w'-ith(and)%[]
Password QueryEscape: my%21pass%2Aw%27-ith%28and%29%25%5B%5D
Password PathEscape: my%21pass%2Aw%27-ith%28and%29%25%5B%5D
Password Correct RFC Escape : my!pass*w'-ith(and)%25%5B%5D
