Invoke-WebRequest with a hex value

Viewed 353

I'm trying to curl a payload containing a semi-colon however it fails

Invoke-WebRequest -Uri $uri -Body '{"text" : "foo;"}' -Method Post

Invoke-WebRequest: {"id":"model.incoming_hook.parse_data.app_error","message":"Unable to parse incoming data","detailed_error":"","request_id":"3papdgjsni87untfo7e3rsogpy","status_code":400}

but

Invoke-WebRequest -Uri $uri -Body '{"text" : "foo"}' -Method Post

works fine. I have converted the semi colon to be %3B and this seems to post as ;. My problem then is it converts all %2F strings into slashes - which then break (it needs to be the literal 2F value for some reason).

When using the curl command or in python it's fine, so it's not as if the endpoint is not accepting the ';' value. I have tried single quotes, double quotes, convertto-json, slashes etc. and nothing seems to be working.

1 Answers

To bring together all the information in the coments, there's a few options, depending on what content types your server accepts.

Content-Type: application/json

If it accepts Content-Type: application/json you can use @Jeroen Mostert's answer in the comments:

# raw text in a hashtable
$data = @{ "text" = "foo;%2F" };

# convert to json
$json = ConvertTo-Json -InputObject $data -Compress;

# post as 'application/json'
Invoke-WebRequest -Uri "http://example.org" -Body $json -Method "POST" -ContentType "application/json";

which will send the following HTTP request:

POST http://example.org/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-GB) WindowsPowerShell/5.1.19041.1
Content-Type: application/json
Host: example.org
Content-Length: 18
Connection: Keep-Alive

{"text":"foo;%2F"}

Content-Type: application/x-www-form-urlencoded

By default, PowerShell will post data using Content-Type: application/x-www-form-urlencoded, so you can send your text as follows:

# raw text in a hashtable
$data = @{ "text" = "foo;%2F" };

# convert to json
$json = ConvertTo-Json -InputObject $data -Compress;

# url-encode
$body = [System.Net.WebUtility]::UrlEncode($json);

# post as 'application/x-www-form-urlencoded'
Invoke-WebRequest -Uri "http://example.org" -Body $body -Method "POST";

which will send the following HTTP request:

POST http://example.org/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-GB) WindowsPowerShell/5.1.19041.1
Content-Type: application/x-www-form-urlencoded
Host: example.org
Content-Length: 36
Connection: Keep-Alive

%7B%22text%22%3A%22foo%3B%252F%22%7D

Note - the full json text is url-encoded, but maybe that's not what your server expects.

Custom encoding

If for some reason your server wants the raw json syntax, but the contents of the text property needs to be url-encoded you can do some custom encoding like this:

# raw text in a hashtable
$data = @{
    "text" = "foo;%2F"
};

# url-encode the text
$data.text = [System.Net.WebUtility]::UrlEncode($data.text);

# convert to json
$json = ConvertTo-Json -InputObject $data -Compress;

# post as 'application/x-www-form-urlencoded'
Invoke-WebRequest -Uri "http://example.org" -Body $json -Method "POST";

which will generate the HTTP request:

POST http://example.org/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-GB) WindowsPowerShell/5.1.19041.1
Content-Type: application/x-www-form-urlencoded
Host: example.org
Content-Length: 22
Connection: Keep-Alive

{"text":"foo%3B%252F"}

Hopefully one of these will work for you. If not, there should be enough snippets above to put something together that does :-).

Related