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
Related
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'>
I use in my template:
<g:formRemote id="accountInfoForm" name="updateInfo" url='[controller:"settings", action: "updateProfile"]' onSuccess="triggerReload()" update="personal-info" accept-charset="utf-8">
I have in my form the following submitButton:
<g:submitButton type="submit" class="update-button" name="Update" id="updateInfo"></g:submitButton>
When I click on the submitButton a request to the URL happens though the form is not valid (The errors are displayed)
Of course that the form is not updated because the is an error in the post request. But the request shouldn't be sent at all if the form is not valid.
The standard FormRemote Tag doesn't validate the Form, the Validation is made on the Application Side, that's why you got the Error back.
To send the Form to the URL only when the form is valid you have to use an Client Side Validation like this
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?
I am trying to compose a SAML2 AuthnRequest for OpenAM. I have a URL that I can perform a get against that works, but am having problems composing this into the XHTML post form.
The working URL with query string is
http://internal.authhost.com:8080/opensso/idpssoinit?NameIDFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:transient&metaAlias=%2FMYRealm%2Fidp&spEntityID=https%3A%2F%2Fsaml.salesforce.com&binding=urn%3Aoasis%3Anames%3Atc%3ASAML%3A2.0%3Abindings%3AHTTP-POST&RelayState=webj_captureCustomerDetails
My html form looks like:
<form action="http://internal.authhost.com:8080/opensso/idpssoinit" method="post" target="new">
<input type="text" name="SAMLRequest" value="PHNhbWxwOkF1dGhuUmV..."></input>
<input type="text" name="RelayState" value="webj_captureCustomerDetails"></input>
<input type="submit"/>
</form>
with the value of SAMLRequest being the Base 64 encoded representation of
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="_d7607d551380ac97853a6ff4907c4ef01219be97dd" Version="2.0"
IssueInstant="2008-05-27T07:46:06Z" ForceAuthn="true" IsPassive="false"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumerServiceURL="https://cs4.salesforce.com/?saml=lkjhkljhkljhkjhlkjh"
ProviderName="https://saml.salesforce.com">
<saml:Issuer>https://saml.salesforce.com</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
AllowCreate="true"/>
</samlp:AuthnRequest>
Issuing this form results in an error message from OpenAM stating "Service Provider ID is null"
I can immediately see that the XML does not contain the metaAlias=/MYRealm/idp argument, but the message suggests that it cannot find the spEntityID=https://saml.salesforce.com argument either.
Please advise on where these two properties (metaAlias and spEntityID) need to be specified in the XML.
A link to somewhere specifying how OpenAM COT / IdP configuration maps against SAML AuthnRequest message would also be appreciated.
Problem was that I was accessing the wrong URL, should have been hitting the spssoinit as it was Service Provider intitated SSO
<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.