Curl: invalid character in User-Agent header


I’ve stumbled across an error while trying to load an ssh key from a http url on VyOS 1.1.5. The server (IIS 7.5) would respond to the loadkey command with a 400 Bad Request, but a manual request typed using telnet would succeed.

Looking at network traffic via monitor … traffic detail, curl (used internally by loadkey) sends the following request:

    GET / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
            [Message: GET / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /
        Request Version: HTTP/1.1
    User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8\177 zlib/ libidn/1.15 libssh2/1.2.6\r\n
    Host: myserver.mydomain.local\r\n
    Accept: */*\r\n

Looks reasonable, except that the OpenSSL token ends with \177, which is ASCII 127 (0x7F, “DEL”). This character is disallowed in HTTP 1.1 header field values (the relevant RFC excerpts can be found here), so the server has the full right to reject the request.

I have no idea (and no way to test) whether this issue is caused by the way VyOS packages are built or if it came from upstream Debian. Has anyone else encountered it?

sounds like a curl problem. you could look at hacking /opt/vyatta/sbin/ and use the curl option to change the user agent to something without the \127

Thanks for pointing me to the relevant script. Indeed, explicitly setting a custom user agent works around the issue.

Further research:

  • on today’s Lithium build (150903 [1]) the openssl token is “OpenSSL/0.9.8\200” and loadkey works, as ASCII \200 = 0x80 = 128 is a valid header value character in HTTP 1.1
  • both Helium 1.1.6 and current Lithium use curl 7.21.0
  • starting with 7.26.0, curl dropped all additional tokens from the default user agent string, shrinking it to just “curl/” [2] [3]

So, any of the following would fix the problem in Helium:

  • update curl to at least 7.26.0,
  • update openssl to at least 0.9.8zg (the version currently being used in Lithium),
  • modify to specify a custom user agent for curl.

[2] shorter HTTP requests for curl |
[3] curl - Changes