2

My username is user1 and password is mypass8@

I wish to pass this username and password to curl command.

How do i escape the @ in the password when passing it to curl command ?

curl -k -X POST https://user1:mypass8@@myshop.com/job/build

I get the error message:

MESSAGE:Invalid password/token for user: user1

I also tried the following but all fail stating the password is not right as the 2 charecter and not considered in the password by the curl command.

curl -k -X POST https://'user1:mypass8@'@myshop.com/job/build
curl -k -X POST https://"user1:mypass8@"@myshop.com/job/build
curl -k -X POST https://user1:"mypass8@"@myshop.com/job/build
curl -k -X POST https://user1:'mypass8@'@myshop.com/job/build

Update: the login I m trying is for Jenkins admin console.

Can you please suggest ?

1

4 Answers 4

4

URLs use percent-encoding aka URL encoding.

@ sign is %40 in this encoding.

% curl -k -X POST https://user1:mypass8%40@myshop.com/job/build

Or alternatively with -u / --user parameter:

% curl -u user1:mypass8@ -k -X POST https://myshop.com/job/build

RFC 3986 section 3.2.1 states:

The userinfo subcomponent may consist of a user name and, optionally, scheme-specific information about how to gain authorization to access the resource. The user information, if present, is followed by a commercial at-sign ("@") that delimits it from the host.

  userinfo    = *( unreserved / pct-encoded / sub-delims / ":" )

Use of the format "user:password" in the userinfo field is deprecated. Applications should not render as clear text any data after the first colon (":") character found within a userinfo subcomponent unless the data after the colon is the empty string (indicating no password). Applications may choose to ignore or reject such data when it is received as part of a reference and should reject the storage of such data in unencrypted form. The passing of authentication information in clear text has proven to be a security risk in almost every case where it has been used.

Applications that render a URI for the sake of user feedback, such as in graphical hypertext browsing, should render userinfo in a way that is distinguished from the rest of a URI, when feasible. Such rendering will assist the user in cases where the userinfo has been misleadingly crafted to look like a trusted domain name (Section 7.6).

Tested with this tiny Go application:

package main

import (
    "log"
    "net/http"
)

func auth(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        user, pass, _ := r.BasicAuth()
        if !check(user, pass) {
            http.Error(w, `Unauthorized.`, 401)
            return
        }
        fn(w, r)
    }
}

func check(user string, pass string) bool {
    if user == `user` && pass == `pass@` {
        return true
    }

    return false
}

func index(writer http.ResponseWriter, request *http.Request) {
    writer.Write([]byte(`hello, world!`))
}

func main() {
    http.HandleFunc("/", auth(index))
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

Run server:

% go run .

Test:

% curl -k -X POST http://user:pass%40@127.0.0.1:8080/ 
hello, world!

% curl -k -X POST http://user:pass@127.0.0.1:8080/ 
Unauthorized.

% curl --version
curl 7.72.0 (x86_64-pc-linux-gnu) libcurl/7.72.0 OpenSSL/1.1.1g zlib/1.2.11 zstd/1.4.5 libidn2/2.3.0 libpsl/0.21.1 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.41.0
Release-Date: 2020-08-19
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd
1
  • I have had to do exactly this with @s and :s in HTTP basic-auth passwords in the past.
    – DopeGhoti
    Sep 17, 2020 at 15:43
1

I have had success with URL-encoding the @s. The problem is that when you say http://myuser:myp@ssword@host.example.com/file, it sees the username as myuser, the password as myp, and the host as ssword@host.example.com which is obviously wrong.

So if you do something like:

user="myuser"
pass="$( printf 'myp@ssword' | sed 's/@/%40/g' )"
curl "https://${user}:${pass}@host.example.com/file"

you should have better luck.

3
  • i tried your suggestion and i still get Invalid password/token error
    – Ashar
    Sep 17, 2020 at 15:50
  • @Ashar Is the service that you're trying to authenticate with expecting a plaintext password, or a password that has been base64 encoded (or encoded with some other encoding)?
    – Kusalananda
    Sep 17, 2020 at 16:36
  • The service is Jenkins admin console page to which I need to login using curl
    – Ashar
    Sep 17, 2020 at 16:44
0

Since I don't know what the website looks like (assuming myshop.com is just an example) I am not sure if this could help. Have you tried "-F" instead of "-X POST"? In case you are filling out a form that should work. That way you could put your password inside a file and call that files content with "<" like so:

curl -F password=</home/user/pw-file -F user=user1 myshop.com/job/build
1
  • Unfortunately, I need -X POST as a requirement here :(
    – Ashar
    Sep 17, 2020 at 15:51
0

Not working:

curl -u user1:mypass8@ -k -X POST https://myshop.com/job/build

Working:

curl -u 'user1:mypass8@' -k -X POST https://myshop.com/job/build

The single quote '' is required if you have @ in your password

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.