Pay Pal REST API "unsupported_grant_type" - paypal

I am trying to get an access token from the Pay Pal REST API, following this article: https://developer.paypal.com/docs/api/overview/#get-an-access-token
My request looks like this:
POST https://api.paypal.com/v1/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Accept-Language: en_US
Authorization: Basic [redacted]
Host: paypal.com
Content-Length: 31
Expect: 100-continue
Connection: Keep-Alive
grant_type=client_credentials
But I keep getting 400 Bad Request with the following response data:
{ “error”: “unsupported_grant_type”, “error_description”: “unsupported grant_type” }
I can't figure out why - as far as I can see, I've followed the instructions exactly!
Their "Merchant Techincal Support" has been absolutely no help.

TLDR; PayPal REST API's GetAccessToken endpoint does not trim whitespace.
I solved it. The astute will notice the following discrepancy:
Content-Length: 31
...
grant_type=client_credentials
The data is only 29 characters - the extra two being \r\n carriage return and line feed.
In code (I'm using C#/.NET) this was a matter of changing:
writer.WriteLine("grant_type=client_credentials");
To
writer.Write("grant_type=client_credentials");
This corrected the issue.

If you're using Postman, add it to Params tab. Like so:

Related

Response to TRACE http method

So I was testing my website and I tried connecting with the TRACE http method. In response I got a massive string. I don't know what it is. Does anybody know what could it be and if it's some sort of vulnerability?
This is the string I'm talking about:
VFJBQ0UgLy5odHBhc3N3ZCBIVFRQLzEuMQ0KSG9zdDogd3d3LnNzZmt6LnNpDQpVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoWDExOyBMaW51eCB4ODZfNjQ7IHJ2OjkxLjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvOTEuMA0KQWNjZXB0OiB0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSxpbWFnZS93ZWJwLCovKjtxPTAuOA0KQWNjZXB0LUxhbmd1YWdlOiBlbi1VUyxlbjtxPTAuNQ0KQWNjZXB0LUVuY29kaW5nOiBnemlwLCBkZWZsYXRlDQpDb25uZWN0aW9uOiBrZWVwLWFsaXZlDQpDb29raWU6IGpzQ29va2llV2FybmluZ0NoZWNrPWRlY2xpbmVkDQpVcGdyYWRlLUluc2VjdXJlLVJlcXVlc3RzOiAxDQpDYWNoZS1Db250cm9sOiBtYXgtYWdlPTAsIG5vLWNhY2hlDQpPcmlnaW46IGh0dHA6Ly93d3cuc3Nma3ouc2kNClByYWdtYTogbm8tY2FjaGUNCg0K
It's a Base64 encoded string. Decoded it looks like this:
TRACE /.htpasswd HTTP/1.1
Host: www.ssfkz.si
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: jsCookieWarningCheck=declined
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0, no-cache
Origin: http://www.ssfkz.si
Pragma: no-cache
Which per se does not really look like a security flaw and much rather like a basic implementation of the TRACE http method which states that the contents of the request shall be reflected in their entirety in the response body.
Interesting note though, looking at the specification:
A client MUST NOT generate header fields in a TRACE request containing sensitive data that might be disclosed by the response. For example, it would be foolish for a user agent to send stored user credentials [RFC7235] or cookies [RFC6265] in a TRACE request. The final recipient of the request SHOULD exclude any request header fields that are likely to contain sensitive data when that recipient generates the response body.
So ideally the response should not have contained the Cookie header (to fully comply with the specification by my understanding the client you used to send the requests should not have included them in the first place however).

Generate Sequential POST requests via fiddler

I am quite new to Fiddler and it looks like an awesome tool to me.
What i wanted to do is generate a sequence of POST requests.
Explaination:
POST https://www.website.com/user/login HTTP/1.1
Host: www.website.com
Connection: keep-alive
Content-Length: 552
Cache-Control: max-age=0
Origin: https://www.website.com
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Referer: https://www.website.com/user/login
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: ASP.NET_SessionId=mpdxdkrjujkzchwblg1ys2y3; ai_user=u0IpN|2018-09-25T16:12:07.607Z; ai_session=+Ip5T|1537899054881.5|1537899121420.5
__VIEWSTATE=something here PageContent%24txtRoll=14600&ctl00%24PageContent%24txtDOB=01%2F01%2F2001&ctl00%24PageContent%24btn_submit=LOGIN
i want to make a loop of request such that the DOB field takes value like
01%2F01%2F2001
then, 01%2F02%2F2001
then, 01%2F03%2F2001
and so on.. keeping everything else same.
And if the response from server is Code:302 then stop the loop or otherwise if the value reaches 31 then too stop the loop.
Thanks in advance.
Any suggestions are welcome.
P.S. :Sorry for the messy question, i don't know how could i say it in simple words.
You need to write a script which will do that for you. Here's an article that might help you.
https://www.telerik.com/blogs/understanding-fiddlerscript
Personally I'd write a script that does the task in python or any other language you know using any http library

Scooping headers off of one Postman request and injecting them into others

My web service uses JWT-based authorization bearer token authentication:
HTTP clients send a valid POST to /v1/auth/signIn with a valid JSON request entity (includes username + password info)
If they authenticate successfully, that endpoint sends back an auth bearer token as an HTTP response header that (from curl) looks like:
Response from curl:
HTTP/1.1 200 OK
Date: Tue, 04 Sep 2018 01:18:28 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Access-Control-Expose-Headers: Authorization
Authorization: Bearer <big_huge_string>
Content-Length: 0
Subsequent service calls to authenticated endpoints just need to include the token as an HTTP request header whose key/name is Authorization and whose value is "Bearer <xyz>" (where <xyz>) is the <big_huge_string> that came back on the sign in call above. Pretty basic standard JWT stuff.
I'm trying to write a Postman collection that starts with a "Sign In Request" that successfully signs in and gets a JWT token from the service, and then adds the appropriate HTTP request header in each subsequent call. Any ideas as to how I can:
Extract the <big_huge_string> off the HTTP response header that I'll get back from my Sign In Request?; and then
How to save that <big_huge_string> as a variable and inject that as an HTTP request header for all subsequent calls?
Thanks in advance!
Update
Tried the suggestion:
Getting closer, but console.log(...) isn't printing anything to Postman (or at least I don't know where to look for it). I should mention I'm not using the Chrome Application version of Postman, but the standalone app/executable (Version 6.1.4):
Any ideas how/where I can get console.log(...) working? I'm concerned about just changing the test to:
pm.test("Can Extract JWT", function() {
var authHeader = pm.response.headers.toObject().Authorization;
pm.expect(authHeader).to.not.be.equal(null);
pm.globals.set('token', authHeader)
});
Without first seeing what that authHeader even is. Any ideas?!
Once you have that Token value you can reference it in each of the request headers using the {{token}} syntax. It's getting the sign in Auth header that's the harder part.
You could use pm.response.headers to get a list of the Headers and then extract out the value that you need.
This is returned as a list so maybe using something like Lodash or converting this to an object can help get the value you need. It would be something like pm.response.headers.toObject().Authorization - I haven't tried it so my syntax might be slightly wrong.
You can log the Headers out to the Postman console and narrow it down that way to - just wrap it in a Console.log() statement.
When you get that value, it's just a basic pm.globals.set('token, pm.response.headers.toObject().Authorization) to save this globally.

Parse returns empty 400 to POST request

Every time I send a pretty minimal request to Parse API:
POST /1/some_url HTTP/1.1
X-Parse-Application-Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Parse-REST-API-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{"data":"value"}
I get the same empty response:
HTTP/1.1 400 BAD_REQUEST
Content-Length: 0
Connection: Close
And ideas about possible errors on my part?
Answering my own question. In my case an additional header was needed:
Host: api.parse.com

Missing detail in answer to HTTP-OPTION

I'm trying to find out the problem in a communication issue between my klient and a REST API.
I can identify the problem but I'm not sure what is exactly missing in the answer for the OPTION request.
My application is creating a HTTP POST what is preflighted by the browser with a HTTP-OPTION. The option is asking for approving the custom Content-type. After the server answers the OPTION the POST is not sent.
OPTIONS /element_collection/VizRundown/channels/ExampleChannel/playlists/continuous/ HTTP/1.1
Host: localhost:8580
User-Agent: Mozilla/5.0.........
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US......
Origin: null
Here is how the answer looks like:
200 OK
Access-Control-Allow-Origin: *
Allow: GET, POST, OPTIONS
Content-Type: text/plain
Server: MediaSequencer/1.23.1.11957 soul/014dfd135460
Transfer-Encoding: chunked
Am I correct that there should be a line int the answer approving the requested Content-Type? Like this:
Access-Control-Allow-Headers: content-type
No, it is not required as per the relevant sections of the spec.
http://www.w3.org/TR/cors/#resource-preflight-requests:
In response to a preflight request the resource indicates which
methods and headers (other than simple methods and simple headers) it
is willing to handle and whether it supports credentials.
http://www.w3.org/TR/cors/#terminology:
A header is said to be a simple header if the header field name is an
ASCII case-insensitive match for Accept, Accept-Language, or
Content-Language or if it is an ASCII case-insensitive match for
Content-Type and the header field value media type (excluding
parameters) is an ASCII case-insensitive match for
application/x-www-form-urlencoded, multipart/form-data, or text/plain.