15

We are passing a ssh public key via an API call, using POST. The strange thing is, when we get the value in PHP, the plus (+) signs are completely stripped. Clearly, this does not work, as it changes the value of the public key.

See the following raw curl request:

curl "https://api.example.com/v1/keys" -X POST -d "key=ssh-dss AAAAB3NzaC1kc3MAAACBAOLsyYuyI0/3/UjajY8ljdgkAV2k9jZxjlVGWvHa9afMuO7DqsOcu0o4e5D9TPScsO5XrgTrmcXHkOtM54fOPdXSzonWOXUIn1XEumdHDlv9YRZTCW/A9qajhPR67y+92su9AqeGXI0/q3BXZsZcC1nr1NjgSiz++r+YZFVWfQsNAAAAFQCYBf0KXVLfYUE6cOTbWnBWn5Py9QAAAIEA3WAkAwhR7fhwWpxuwxNnsB8NXwsEs2NWiOaiMu3dmDWyqGRjfOYUchoLelBMpv4oLTZuaGW4/DCWfdh6pgrxs39MXf+FdTir8KeHIIoXEdcXpWqnuyNBdXn5XNY54vc1eMkbm4q3D1i3+IMhNAURasdvFRoDzgH9s68Ik3P5HrMAAACAab+CiT010wXMzv+6v+oWcRWbxhGou/ND+K2QGU1kAW+KuUGmhOgB6XPka7iEsIeA/+Ojh+OiNedFZlJAZq1jarew106YCOrUlbtDk7pAAUJQhIhKFhpNE0UhLRBWOF9LpjDwWu55dlrfLURE32TuMx/NsazWVypbzJqy48d2sg8= justin@mbpro"

But, when we var_dump() out the value of $_POST['key'] in our PHP it is:

string(601) "ssh-dss AAAAB3NzaC1kc3MAAACBAOLsyYuyI0/3/UjajY8ljdgkAV2k9jZxjlVGWvHa9afMuO7DqsOcu0o4e5D9TPScsO5XrgTrmcXHkOtM54fOPdXSzonWOXUIn1XEumdHDlv9YRZTCW/A9qajhPR67y 92su9AqeGXI0/q3BXZsZcC1nr1NjgSiz  r YZFVWfQsNAAAAFQCYBf0KXVLfYUE6cOTbWnBWn5Py9QAAAIEA3WAkAwhR7fhwWpxuwxNnsB8NXwsEs2NWiOaiMu3dmDWyqGRjfOYUchoLelBMpv4oLTZuaGW4/DCWfdh6pgrxs39MXf FdTir8KeHIIoXEdcXpWqnuyNBdXn5XNY54vc1eMkbm4q3D1i3 IMhNAURasdvFRoDzgH9s68Ik3P5HrMAAACAab CiT010wXMzv 6v oWcRWbxhGou/ND K2QGU1kAW KuUGmhOgB6XPka7iEsIeA/ Ojh OiNedFZlJAZq1jarew106YCOrUlbtDk7pAAUJQhIhKFhpNE0UhLRBWOF9LpjDwWu55dlrfLURE32TuMx/NsazWVypbzJqy48d2sg8= justin@mbpro"

Any idea what is causing the plus signs to be removed?

Justin
  • 42,716
  • 77
  • 201
  • 296

4 Answers4

36

+ plus characters in form data are interpreted as space characters by some servers.

You can avoid this by encoding the plus characters in the form data as %2B. Instead of using -d/--data, use cURL's --data-urlencode parameter to do this.

PHP's rawurlencode function could perform the same encoding if you were constructing an outgoing request. However, when incoming response data is accessed by your PHP script on the server, it has already been automatically decoded, so you don't need to (and shouldn't) call rawurldecode yourself.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • 1
    Be careful, it's not in every case that + is encoded as %20. http://stackoverflow.com/questions/996139/php-urlencode-vs-rawurlencode/6998242#6998242 – Incognito Sep 14 '11 at 02:09
  • Yeah that is a problem, we don't want to have to require users to manually go through the public key when they copy and paste it in the and API and replace plus signs with %2B. Could we hack it on the backend, and replace spaces with + signs, since we know that ssh public keys will never have spaces? – Justin Sep 14 '11 at 02:12
  • 1
    Instead of using `-d`, try using `--data-urlencode`. I think it should handle this for you. – Jeremy Sep 14 '11 at 02:14
  • --data-urlencode works, just have to specify that in the documentation that they MUST use that flag, instead of -d – Justin Sep 14 '11 at 02:24
0

You have to pass a suitably URL-encoded string to the data argument for curl. You can use an online URL encoder for one-off situations.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
-1

Do you have magic quotes turned on?

Here is an existing question that addresses a similar issue: Why are $_POST variables getting escaped in PHP?

You also need to url encode post values even though they aren't going directly into the URL like a get value.

Community
  • 1
  • 1
Matt Wonlaw
  • 12,146
  • 5
  • 42
  • 44
-1

You may also want to consider using base64encode instead of urlencode. Sometimes urlencode/decode will do unexpected things, though I think it'll work for you in this instance as well.

http://php.net/manual/en/function.base64-encode.php

Brane
  • 3,257
  • 2
  • 42
  • 53
Homer6
  • 15,034
  • 11
  • 61
  • 81