cURL post to PayPal succeeds while HTML Form post and RunScope post fail - forms

I'm currently developing an integration with PayPal's Payflow Pro Gateway. I'm sending a request to PayPal to get their "Secure Token" so that I can use that to do the real transaction. A sample I found on SO works via cURL, but the original HTML Form POST and RunScope tests I ran did not work.
Here is the cURL command:
curl https://pilot-payflowpro.paypal.com -kd "PARTNER=PayPal&VENDOR=*****&USER=*****&PWD=*****&TRXTYPE=A&AMT=40&CREATESECURETOKEN=Y&SECURETOKENID=*******&SILENTTRAN=TRUE"
Per the cURL documentation:
The -k option is:
"(SSL) This option explicitly allows curl to perform "insecure" SSL
connections and transfers. All SSL connections are attempted to be
made secure by using the CA certificate bundle installed by default.
This makes all connections considered "insecure" fail unless -k,
--insecure is used."
The -d option is:
"(HTTP) Sends the specified data in a POST request to the HTTP server,
in the same way that a browser does when a user has filled in an HTML
form and presses the submit button. This will cause curl to pass the
data to the server using the content-type
application/x-www-form-urlencoded. Compare to -F, --form."
-d, --data is the same as --data-ascii. To post data purely binary, you should instead use the --data-binary option. To URL-encode the
value of a form field you may use --data-urlencode.
If any of these options is used more than once on the same command
line, the data pieces specified will be merged together with a
separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would
generate a post chunk that looks like 'name=daniel&skill=lousy'.
If you start the data with the letter #, the rest should be a file
name to read the data from, or - if you want curl to read the data
from stdin. The contents of the file must already be URL-encoded.
Multiple files can also be specified. Posting data from a file named
'foobar' would thus be done with --data #foobar. When --data is told
to read from a file like that, carriage returns and newlines will be
stripped out.
That works great and returns this response:
RESULT=0&SECURETOKEN=*****&SECURETOKENID=*****&RESPMSG=Approved
HTML Form POST
However, what I perceive to be the same request fails in the following HTML form POST:
<input type="hidden" name="TRXTYPE" value="A" />
<input type="hidden" name="SILENTTRAN" value="TRUE" />
<input type="hidden" name="AMT" value="40" />
<input type="hidden" name="CREATESECURETOKEN" value="Y" />
<input type="hidden" name="SECURETOKENID" value="*****" />
<input type="submit" value="Get Secure Token" />
That gives me "The connection was reset" in FireFox.
I also tried using jQuery to POST the data using $.ajax(), but I received a 200 response with no data in it.
Runscope
When I enter the above parameters into RunScope, I get:
RESULT=1&SECURETOKENID=*****&RESPMSG=User authentication failed
Which doesn't make any sense!
I was thinking that PayPal is either doing something with examining the user agent, or request headers, but I don't have any real idea. Can anyone shed some light on this behavior?

Related

How Do I Authenticate an API Request Using a Token With Postman

I am trying to test a Web API using Postman on a project which I have inherited from previous developers. All I know so far is that Authentication has been configured using ASP.Net Identity and Identity Server 4.0 which implements OAuth and issues short lived JSON Web Tokens (JWT) and Refresh Tokens.
If I navigate to the development website, log in (successfully), and use Chrome Developer Tools to inspect the initial log in request I can see that the body of the request contains a Form with 3 fields; userName, password and returnUrl. If I right-click on the request I can copy the request as cURL (bash) and in Postman I can import the data to create a new request. If I send the request I get a status 200 OK back and the response includes 6 cookies. However the body of the response contains an htlm page which Postman can't render and a message You need to enable JavaScript to run this app.
I'm lost now as to how I can use the response to authenticate a request for some data. Is the Token I need contained within one of the cookies? How do I extract the Token and use it within a request for some data? Any advice or suggestions would be very welcome.
Normally, with JavaScript enabled in the browser, <form> would be automatically posted to its' destination defined in action, using method. JavaScript would do somethign like the following:
window.addEventListener('load', function(){document.forms[0].submit();});
So without JavaScript, you would need to somehow parse the form that you received and recreate equivalent request.
The form, received upon successful login, contains data that should be sent back to your origin website, to authenticate the end-user.
For example, form's body contains hidden input fields, defined by OpenID protocol:
...
<input type='hidden' name='token_type' value='Bearer' />
<input type='hidden' name='expires_in' value='600' />
...
Form action attribute points back to sign-in endpoint on your website. For example:
<form method='post' action='https://{hostname:post}/signin-oidc'>

Sails JS forbidden POST request

I'm trying to learn Sails JS and obviously REST API.
I've created a user model wich I think works fine (it communicates datas with my db). I've also created a signup controller with 4 needed inputs to store a new record in my user collection. (Some other datas are generated by this controller to complete the record at the moment of the registration)
I would like to test this controller with POSTMAN, so I go to my routes.js and see :
'POST /api/v1/entrance/signup': { action: 'entrance/signup' },
But when i enter a POST request at 192.168.1.13:1338/api/v1/entrance/signup with my 4 needed inputs declared I have this answer : Forbidden
I don't know what I do wrong. I've also enabled rest, shortcuts and actions in my blueprints.js
Does someone has an idea ? :)
The issue is indeed related to cross-site request forgery, but disabling the corresponding security rule altogether is quite obviously not a solution. CSRF and its treatment in sailsjs are well described in the corresponding part of the manual. In short, for POSTs to work you have to include _csrf in your requests. E.g. in a view template:
<form>
<input type="hidden" name="_csrf" value="<%- _csrf %>" />
</form>
As said below, removing CSRF protection is not an answer as it may expose the api to a security breach. I currently use JWT but it doesn't seems to be as secure as CSRF token so the only right way is to include the token in every HTTP's request header.

Posting to Facebook without a link

I'm working on an API to allow posting to Facebook, using Graph API over REST, sending HTTP post requests to https://graph.facebook.com/me/feed (after succesful OAuth2 auth).
I can specify message and link and it posts the link, (but with message ignored?), and I can also include name, caption and description to get those elements handled - so links are ok.
If I use just message or just picture, I get the error:
(#100) Missing message or attachment
If I use message and picture, it posts the message, without any picture. (Which is useful, but not intended behaviour?)
The only way I can get the picture seems to be as a link (which includes it as a thumbnail).
I've looked through the docs but can't find any useful info on this - all the examples are showing links.
My main question is: What is the intended way to post a message without a picture or link?
But it'd also be useful to know if there's a way to post a picture to the wall? (non-thumbnail, with lightbox)
The actual code is more complex, but simplified here to demonstrate the issue.
This was failing:
<cfhttp
result = "local.Response"
method = "post"
url = #Arguments.Url#
>
<cfhttpparam type="url" name="Message" value="#Arguments.Message#" />
</cfhttp>
This worked:
<cfset Arguments.Url &= '&message=' & encodeForUrl(Arguments.Message) />
<cfhttp
result = "local.Response"
method = "post"
url = #Arguments.Url#
>
<cfhttpparam type="url" name="dummy" value="ignore" />
</cfhttp>
(The dummy cfhttpparam is because CF complains if a POST request doesn't contain at least one param.)

Plupload upload file missing xsrf argument in tornado xsrf mode?

WARNING:root:403 POST /upload (127.0.0.1): '_xsrf' argument missing from POST
WARNING:root:403 POST /upload (127.0.0.1) 2.95ms
What did I deal with?
The server to which you are attempting to upload a file does not allow uploads without the appropriate XSRF value. This value is supplied by per-user cookie.
Apart from having the appropriate cookie, you must ensure that your upload form contains a field for this value. Tornado provides a xsrf_form_html() function which you'd call from your form, e.g.:
<form action="/upload" method="post">
{{ xsrf_form_html() }}
<input type="text" name="foo"/>
<input type="submit" value="Upload"/>
</form>
References:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
http://www.tornadoweb.org/documentation/overview.html?highlight=forgery#cross-site-request-forgery-protection

GET parameters are lost when submitting a form with POST method in CGI?

<form method="POST" action="/index?key=1">
<input type="text" name="another_key" value="2" />
</form>
When I submit such a form and trying to fetch the GET parameter with CGI->new->param('key'),
it doesn't work..
Can CGI work when both GET and POST parameters exist?
For a POST request, CGI's param method will only get post parameters, but there is an alternate url_param method that will provide the "GET" parameters from the url.
This can be very helpful for file uploads; if the post request is too large, it will be entirely discarded, but the url parameters can tell you what kind of upload it was so you can show the user an error message in the correct context.