AJAX prevention of XSS attack - ajax

I am using Latest Web server(Any) which are by default enabled with X-XSS-Protection:1; mode=block to block the possible XSS attackes.
So tried to assess my server with injection of script on to a GET request which was rejected by the server due the above filter enabled.My request looks like
https://localhost:431/report/api/createlist.ams?subscriberID=%3Cscript%3Ealert(1)%3C/script%3E&_=1490175834029 ==> Rejeted by server because the source code of a script was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior.
I have some GET requests via AJAX which are still not blocked by server. Server is treating normal GET request and AJAX GET request are different. How could i reject a XSS attack is case of AJAX request as below mentioned.
https://localhost:43261/tabular/reports-data/items.json?startDate=2017-03-01&endDate=2017-03-22&Type=All&bound=Inbound&dataGrouping=%3C%2Ftitle%3E%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E%3Ctitle%3E&=1490244895514
OR
https://localhost:43261/tabular/reports-data/items.json?startDate=2017-03-01&endDate=2017-03-22&Type=All&bound=Inbound&dataGrouping=%alert(1)%&=1490244895514
Thanks

Related

What does "Response to preflight request doesn't pass access control check" mean?

I have receive the following response when trying to access an API via an ajax request in Chrome:
"Failed to load http://localhost:1880/api_resource: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:3000 is therefore not allowed access."
As you can see from the message, both client and API are running locally.
I understand that this situation relates to a CORS cross origin request. I see that there are similar questions about this on stack overflow, but from those answers I do not understand what the message is telling me and where it comes from.
Specifically I understand that the response header "Access-Control-Allow-Origin" must be set (typically to '*') to allow access to the API from a different domain to the one on which the API is being served. But the message seems to relate to the request and not the response, and as far as I am aware, no request ever reaches the API.
What is a preflight request and how is it failing?
As I now understand it, modern browsers will issue a 'preflight' request before the actual cross origin request. This preflight request uses the 'OPTIONS' HTTP verb along with the CORS headers Access-Control-Request-Method and Access-Control-Request-Headers to which it expects to see a response with valid Access-Control-Allow-Origin in the header that indicates that the server understands the CORS protocol and will allow the actual (GET/POST/PUT) request.
The message "Response to preflight request doesn't pass access control check" means that the browser did not see a valid "Access-Control-Allow-Origin" header in the Options response.
In my case this was because the server (implementing a REST API) was set up to respond correctly to PUT and POST requests but not setup to respond to OPTIONS requests with the CORS headers.
in my case the problem was for my website address, i'm calling all apis from the same server but i got this error.
my website address is sateh.ir
so im my ajax request i set the url: http://sateh.ir/api/...
after getting this error and working on it for some hours, i got that i had to set ajax url to: http://www.sateh.ir/api/...
i dont know why my website cant understand that i'm calling api from the same server if i dont put 'www', but that was my problem at all.

Do browsers allow cross-domain requests to be "sent"?

I am newbie to website security and currently trying to understand Same-Origin-Policy in some depth.
While there are very good posts on stackoverflow and elsewhere about the concept of SOP, I could not find updated information on whether chrome and other browsers allow cross-domain XHR post requests to be 'sent' from the first place.
From this 5 year old post, it appears that chrome allows the request to pass through to the requested server but does not allow reading the response by the requester.
I tested that on my website trying to change user info on my server from a different domain. Details below:
My domain: "www.mysite.com"
Attacker domain: "www.attacker.mysite.com"
According to Same-Origin-Policy those two are considered different Origins.
User (while logged in to www.mysite.com) opens www.attacker.mysite.com and presses a button that fires a POST request to 'www.mysite.com' server...The submitted hidden form (without tokens in this case) has all the required information to change the user's info on 'www.mysite.com' server --> Result: CSRF successful attack: The user info does indeed change.
Now do the same but with javascript submitting the form through JQuery .post instead of submitting the form--> Result: Besides chrome giving the normal response:
No 'Access-Control-Allow-Origin' header is present on the requested
resource
, I found that no change is done on the server side...It seems that the request does not even pass through from the browser. The user info does not change at all! While that sounds good, I was expecting the opposite.
According to my understanding and the post linked above, for cross-domain requests, only the server response should be blocked by the browser not sending the post request to the server from the first place.
Also, I do not have any CORS configuration set; no Access-Control-Allow-Origin headers are sent. But even if I had that set, that should apply only on 'reading' the server response not actually sending the request...right?
I thought of preflights, where a request is sent to check if it's allowed on the server or not, and thus blocking the request before sending its actual data to change the user info. However, according to Access_Control_CORS , those preflights are only sent in specific situations which do not apply to my simple AJAX post request (which includes a simple form with enctype by default application/x-www-form-urlencoded and no custom headers are sent).
So is it that chrome has changed its security specs to prevent the post request to a cross domain from the first place?
or am I missing something here in my understanding to the same-origin-policy?
Either way, it would be helpful to know if there is a source for updated security measures implemented in different web browsers.
The XMLHttpRequest object behavior has been revisited with time.
The first AJAX request were unconstrained.
When SOP was introduced the XMLHttpRequest was updated to restrict every cross-origin request
If the origin of url is not same origin with the XMLHttpRequest origin the user agent should raise a SECURITY_ERR exception and terminate these steps.
From XMLHttpRequest Level 1, open method
The idea was that an AJAX request that couldn't read the response was useless and probably malicious, so they were forbidden.
So in general a cross-origin AJAX call would never make it to the server.
This API is now called XMLHttpRequest Level 1.
It turned out that SOP was in general too strict, before CORS was developed, Microsoft started to supply (and tried to standardize) a new XMLHttpRequest2 API that would allow only some specific requests, stripped by any cookie and most headers.
The standardization failed and was merged back into the XMLHttpRequest API after the advent of CORS. The behavior of Microsoft API was mostly retained but more complex (read: potentially dangerous) requests were allowed upon specific allowance from the server (through the use of pre-flights).
A POST request with non simple headers or Content-Type is considered complex, so it requires a pre-flight.
Pre-flights are done with the OPTIONS method and doesn't contain any form information, as such no updates on the server are done.
When the pre-flight fails, the user-agent (the browser) terminate the AJAX request, preserving the XMLHttpRequest Level 1 behavior.
So in short: For XMLHttpRequest the SOP was stronger, deny any cross-origin operations despite the goals stated by the SOP principles. This was possible because at the time that didn't break anything.
CORS loosened the policy allowing "non harmful" requests by default and allowing the negotiation of the others.
OK...I got it...It's neither a new policy in chrome nor missing something in SOP...
The session cookies of "www.mysite.com" were set to "HttpOnly" which means, as mentioned here, that they won't be sent along with AJAX requests, and thus the server won't change the user's details in point (4).
Once I added xhrFields: { withCredentials:true } to my post request, I was able to change the user's information in a cross-domain XHR POST call as expected.
Although this proves the already known fact that the browser actually sends the cross-domain post requests to the server and only blocks the server response, it might still be helpful to those trying to deepen their understanding to SOP and/or playing with CORS.

AJAX calls to web service with HTTPS protocol

I plan to use https to build a website. After the user logs in, s/he is directed to a dashboard. The dashboard will be developed using javascript and html5. What are the thing I need to keep in mind when I make ajax calls using SOAP to a web service while using https?
The most important things:
always use the same domain name, otherwise browser will throw cross domain errors,
always use https protocol for every ajax request, so browser won't get same origin errors.
On the server side check for X-Requested-With: XMLHttpRequest HTTP header, to be sure that the request came as AJAX, not standalone GET/POST request. This is only difference.
With AJAX request browser will send the same cookies value as in the any other request, so you can surely check user session with it.

Why is ExtJS sending an OPTIONS request to the same domain?

I'm loading my script on a domain and sending some data with POST and the use of Ext.Ajax.request() to that same domain.
Somehow the dev-tools show me, that there is a failed OPTIONS request.
Request URL : myurl-internal.com:8090/some/rest/api.php
Request Headers
Access-Control-Request-Headers : origin, x-requested-with, content-type
Access-Control-Request-Method : POST
Origin : http://myurl-internal.com:8090
It's both HTTP and not HTTPS. Same port, same host ... I don't know why it's doing this.
The server can't handle such stuff and so the request fails and the whole system stops working.
It's not really specific to Ext JS -- see these related threads across other frameworks. It's the server properly enforcing the CORS standard:
for HTTP request methods that can cause side-effects on user data (in
particular, for HTTP methods other than GET, or for POST usage with
certain MIME types), the specification mandates that browsers
“preflight” the request, soliciting supported methods from the server
with an HTTP OPTIONS request header, and then, upon “approval” from
the server, sending the actual request with the actual HTTP request
method.
If you're going to use CORS, you need to be able to either properly handle or ignore these requests on the server. Ext JS itself doesn't care about the OPTIONS requests -- you'll receive the responses as expected, but unless you do something with them they'll just be ignored (assuming the server actually allows whatever you're trying to do).
If you are NOT intending to use CORS (which sounds like you aren't purposefully going cross-domain) then you need to figure out why the server thinks the originating domain is different (I'm not sure about that). You could also bypass CORS altogether by using JsonP (via Ext's JsonP proxy).
Use relative url instead of absolute, then you will get expected result.
use before request
Ext.Ajax.useDefaultXhrHeader = false

Can an AJAX response set a cookie?

Can an AJAX response set a cookie? If not, what is my alternative solution? Should I set it with Javascript or something similar?
According to the w3 spec section 4.6.3 for XMLHttpRequest a user agent should honor the Set-Cookie header. So the answer is yes you should be able to.
Quotation:
If the user agent supports HTTP State Management it should persist,
discard and send cookies (as received in the Set-Cookie response
header, and sent in the Cookie header) as applicable.
Yes, you can set cookie in the AJAX request in the server-side code just as you'd do for a normal request since the server cannot differentiate between a normal request or an AJAX request.
AJAX requests are just a special way of requesting to server, the server will need to respond back as in any HTTP request. In the response of the request you can add cookies.
For the record, be advised that all of the above is (still) true only if the AJAX call is made on the same domain. If you're looking into setting cookies on another domain using AJAX, you're opening a totally different can of worms. Reading cross-domain cookies does work, however (or at least the server serves them; whether your client's UA allows your code to access them is, again, a different topic; as of 2014 they do).
Also check that your server isn't setting secure cookies on a non http request. Just found out that my ajax request was getting a php session with "secure" set. Because I was not on https it was not sending back the session cookie and my session was getting reset on each ajax request.

Resources