I have a simple post request that comes from one specific page of my site:
reqdata = 'text=' + mytext;
$.ajax({
type: "POST",
url: "/request.php",
data: reqdata,
cache: false,
success: function(html) {
alert(html)
}
});
It goes to another page of the same site .. So the first page calls page mydomain.com/test.php calls http request to mydomain.com/request.php
How do I recognise on page mydomain.com/request.php that the original page the request come from was mydomain.com/test.php?
I wish to ensure that the request can be done only from this exact page mydomain.com/test.php and not from other domains nor page.
I do the request using ajax and javascript and therefore I think that I cannot add a hidden authentication that would ensure the whole thing is secure. Because each value is seen on the original page source code.
It seems you are searching for a way to protect yourself against Cross Site Request Forgery (XSRF).
The common way to protect against XSRF is to render some time limited key on your page (just some <script> var mySecret = <?php (someSecret) ?>) and keep track of these. You could use the first characters of the session id for example and check if the request data contains this field. You can just add this to your data with something like ...&secret=mySecret When there is a session id with the first characters of this data attribute, you accept the request, otherwise you reject it on your server (possibly with error code 403).
So this question would be
best practices to avoid XSRF on my site
and should be asked on the information security stack exchange.
Related
I have a simple AJAX GET request going to a certain PHP page:
$.ajax({
type: "GET",
url: "http://example.com/remote.php",
success: function(response){
document.getElementById("test").innerHTML = response;
}
});
The remote.php page echoes the $_SERVE['REMOTE_ADDR'] variable. The response of the AJAX request is the IP address of the client itself (from which a user is navigating from).
The JS file containing the AJAX request is located on the same server, e. g. http://example.com/js/ajaxstuff.js.
My objective is to get from which website the PHP page was accessed from, in order to prevent users simply going on the PHP page itself to gather information. Basically, I am trying to get a result of http://example.com or the IP of said server when the page is accessed from AJAX, or the user's IP address if the PHP page was accessed from its browser directly.
Well you could use a ref tag in PHP but this would not give you the correct way of getting this to work.
Option 1: Database.
A way that I would make instead would to create a mysql field with the ip and last loaded in another ajax call that would work as access control. For instance you add that into the normal page and load it with javascript for instance with setInterval() function in javascript.
When that ajax is called then the ip will be added into the table and that sets a unix timestamp.
If that timestamp is longer than 2 minutes since last load then you block your normal script for accessing. This way you can also insert a function to block ips that you know is fake or not good for your script.
Option 2: Set Session in the main php loading page.
You can create a session that you set a magic key for instance $_SESSION["access"]="YOU SECRET KEY"; and then check if this one is inside the remote.php
I would prefer the database version.
How to not copy my source code to other servers and provide them with a JS or iframe like the analytics and statcounter provide us?
I wrote a PHP script with JS that in it's basic description goes like this:
When someone visits my website, gets a cookie with a value of a unique identification and at the same time using AJAX I make some checks and I save that same value to mysql accordingly. After this, if he visits again my site, (in most of the cases) a cookie is not created again.
In depth:
The cookie value is created with JS and I want to keep it that way for future enhancements.
My code (index.php, add-to-mysql.php) has JS and PHP.
I want to use this script in my additional domains, and some of them are in different server. But I don't want to put all my source files to there accounts.
The ideal for me is to provide them with a JS code, like the google analytics or statcounter give us (or alternative similar ways), an iframe... solutions like these.
When a visitor gets into their page, my mySQL in a remote server (my server) will be updated and a cookie will created on their site. Transferring data from and to.
Is this something possible to be made? If yes, how can I start studying for this? Can you provide me with some guidelines?
Thank you.
this is a block of code, the ajax function that posts the random number to the add-to-mysql.php file where i make some actions
$.ajax({
type: 'POST',
url: 'add-to-mysql.php',
data: { one: hash }, //an antikatastiso to hash me to a ke kano to md5 meso php sto ajax vgenei to idio
success: function(data) {
alert("success! X: " + data);
}
});
It seems to me you have three options here.
1. Use JSONP
JSONP allows you to do cross domain ajax calls so that you can just call in to your home server from your other domains without being obstructed.
This is probably the easiest route to go I'm thinking.
See here for a quick write up on how JSONP works:
https://stackoverflow.com/a/2067584/867294
jQuery supports jsonp so it's not to difficult to get started with:
http://learn.jquery.com/ajax/working-with-jsonp/
JSONP works by dynamically adding a script to the document that then calls a callback.
The contents of ths javascript file need to be generated by the server, your PHP file add-to-mysql.php will have to echo out something like this:
<?= htmlspecialchars($_GET["callback"]) =>('someData you want to return');
You can access the one: parameter that was passed in from jQuery trough the $_GET array as well, as this is just a GET request.
From the client side you can call this route like so:
Note that this will always be a GET request, all parameters will go trough the URL.
The 'callback' parameter is the connecting factor here, it makes sure the PHP side knows what JavaScript function to generate.
$.ajax({
jsonp: 'callback',
dataType: "jsonp",
url: 'http://my-server.com/add-to-mysql.php',
data: { one: hash }, //an antikatastiso to hash me to a ke kano to md5 meso php sto ajax vgenei to idio
success: function(data) {
alert("success! X: " + data);
}
});
2. Use CORS
CORS will allow you to make ajax calls to a different domain then the one where your JS is running. This does however require you to send special http headers from the serving html page, so this does require you to modify the servers.
See here for a qucik intro on CORS:
http://www.html5rocks.com/en/tutorials/cors/
In short, the headers you will need to set from the serving html page are:
Access-Control-Allow-Origin: http://domain.com
Access-Control-Expose-Headers: list,of,headers
3. Posting to an iFrame
Posting trough a hidden iFrame is also an option.
For this you need to set the target of a form to the name of the iframe, the advantages here is that you can use POST as well. You can submit and populate the form trough jQuery as well.
$('#one_input').val('someHash');
$('#myForm').submit();
You can just put everything in a hidden div if you don't want to show it on the page:
<div style='display:none;'>
<form id="myForm" action="http://my-server.com/add-to-mysql.php" method="post" target="my_iframe">
<input type="input" id="one_input" value="" />
</form>
<iframe name="my_iframe" ></iframe>
</div>
You could also just set the url of the iframe with your parameter if you don't need any feedback.
var hash = 'stuff';
document.getElementId('one_input').src="http://my-server.com/add-to-mysql.php?one=" + hash;
Extra
you could also use the iframe with Window.postMessage
Building on the previous example:
$('#my_iframe')[0].contentWindow.postMessage('hash', 'my-server.com');
But this requires you to have already a page loaded in your iframe that will then receive the message trough JavaScript, so I don't think this is what you are looking for.
Google Analytics provide an script that doesn't post data, it loads an script asynchronously (this is very important to avoid messing with load times of the original website), then it sends all of their info requesting for a .gif image. Your code should do a request to an url ending in .gif, with all the data in GET form. Do your magic and return a gif with size 1px*1px and no content.
Just request something like this
yourdomain.com/a.gif?cookie=1234aqfajsdlq....&uid=qekjlajdfa
Put all your data in there
I recommend obfuscating it a bit, but that should help you avoid cors, iframes or jsop
EDIT
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'id', 'domain');
ga('send', 'pageview');
</script>
This was taken from GA. See that it creates a tag, with the async attribute to avoid load time issues (remember sync scripts stop the page rendering). Then it creates and array where it pushes all the info it needs in tuples. It defines ga in the window as a function that pushes all its arguments to a q.
The you can create an script that takes all of the data you need, with js, cookies, domain, etc. and send to the server.
For example, you want the domain that the user is visiting:
//You won't have jquery, but you get the idea
//Create a tag
var i = $('<img>').prop('src', 'yourdomain.com/a.gif?domain' + window.location.origin).css('display', 'none');
$('body').append(i);
In some point you will have to set a cookie. I thing cookies can't not be cross domain, so you should set them in your requests not in js.
On the server side you check the cookie, if there is none, you created, and there you can track many things.
Afterwards, your script can check for cors support, and use ajax without this. I don't recommend JSONP, is very error prone, and is actually kind of a hack
In order to avoid the cross-domain problematic you can include an iframe at the other sites, that loads from your site. It creates its own scope (domain) and you can freely use ajax from inside communicating with your site.
However, if you set cookies there, it will be associated to the iframes source domain (your domain). This might or might not be a problem. Note, that this can be used to identify users across all the other domains including this same iframe (from your domain).
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
"CSRF token missing or incorrect" while post parameter via AJAX in Django
I wanted to send login data by AJAX to authenticate user, but it wasn't possible because of CSRF. Could You tell me what to add to my code to make it woking?
my JavaScript file:
$("#login").live("click", function() {
var username = $(".login_username").val();
var password = $(".login_password").val();
$.ajax({
url: "/login",
type: "POST",
data: {
username: username,
password: password
},
cache: false,
success: function(tekst) {
alert(tekst);
}
});
});
There is a method explained here.
It consists of adding a X-CSRFToken header on each ajax request.
This is done by hooking in the jQuery.ajaxSend event, so everything is done automatically (you just have to copy and past their code, and run it once before the first ajax request you make).
I've been trying to solve the same problem, And as arnaud576875 says you have to Add the csrf token header on each ajax request just like the Django docs says https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax And execute that code before any Ajax request you make.
But there is something additional, you have to find a way to load the csrf token to the cookies of your app before trying to do any AJAX request, after a lot of painful hours researching I couldn't find an specific answer of how to do this, what I did found is that to ensure that your view sends the csrf token within a cookie you can use the ensure_csrf_token() to each view you want to receive the token https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#django.views.decorators.csrf.ensure_csrf_cookie this seems to work for a lot of people, but did not worked for me.
Another way is using the Legacy Method, adding the 'django.middleware.csrf.CsrfResponseMiddleware' to your MIDDLEWARE_CLASSES but I don't recommend this method because leaves several security risks.
https://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#legacy-method
All this methods that I said before did not worked for me. The way that I'm allowing Ajax to do some requests is as the following, and if someone finds this a dangerous method please let me know:
Go to the first view that your user will hit, like the /home/ page.
Insert this before redirecting or parsing anything
request.META["CSRF_COOKIE_USED"] = True
And that's it, That is the way that works for me, but as I said before I'm not sure if this is the right method or the most secure one to accomplish the csrf protection.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Load website into DIV
Hey all i am trying to find a way to call an external website and retreve its HTML so that i can check for something in it (wither the user entered a valid VIN # or not depending on what this website calls back)
This is the code i have:
$.ajaxSetup ({
cache: false
});
$("#load_callback").click(function(){
$.ajax({
url: 'http://www.google.com',
dataType: 'text',
success: function(data) {
alert(data);
}
});
});
It works but only if i have it pointed to my server (and running on my server also). Is there a way i can call an external website using jquery/ajax? I am aware of the Same origin policy but was hoping something like what i want to do did not fall into that catagory?
I cant even get an iFrames title? Really??? wow....
David
You need to use jsonp: http://en.wikipedia.org/wiki/JSON#JSONP
These links should explain it:
http://www.remysharp.com/2007/10/08/what-is-jsonp
http://www.ibm.com/developerworks/library/wa-aj-jsonp1-
The other option you have is to write your own server-side proxy to it, i.e. have a page/controller/handler on your server that passes your request through and returns the result. It won't be as fast as going direct, and it will increase your site's traffic, but it will get you around the security problem.
Stick to simple things, if you want to load websites, be simple and go with iframe. If you want to make request use PHP or similar. For example you can use curl method to make request to another websites through PHP. Or even simpler, setup a form to request to another web server.
I've written some HTML/Javascript that sits on a third-party server for security reasons. This page performs a javascript post to another page on the same site. However, instead of responding with useful data, it instead wants to perform a redirect (if you would post via a normal HTML form to this page, it would redirect your browser). How can I process this process? I basically want to be able to extract the url's query parameters that it is trying to redirect with (and then put this link into a hidden form field).
Here is my basic ajax post...
$.ajax({
url: '/someurl/idontcontrol',
data: serialized_form_data,
async: false,
type: 'POST',
success: function(data, textStatus, x) {
alert(x);
alert(x.getAllResponseHeaders());
return false;
$('#redirect_link').val(WHAT_DO_I_PUT_HERE);
}
});
Note that the URL I am posting to is not one that I control, so I have no power over what it returns.
UPDATE: When I use the above alerts, I receive "[object XMLHttpRequest]" and "null". I'm monitoring the headers with a Firefox plugin and they seem be coming back as expected, but I can't seem to access them via javascript (I've also tried x.getResponseHeader('Location'), but that and all other calls to getResponseHeader return empty).
ALSO: I don't know if it matters, but the status code is 302 (as opposed to 301 or 303).
Thanks!
According to the jQuery Documentation the success method can take a third argument which is the XMLHttpRequest object.
According to Mozilla's XMLHttpRequest page, this object should have a "status" property. If you check the value of this property, and it is a redirect code, such as 301 (permanent redirect) or 303 (temporary redirect) it is known the processing page is trying to perform a redirect. The "statusText" property should be able to be used to determine the location it is trying to redirect you to.
If you know it is trying to redirect, you can then re-post the data through Ajax to the new URL.
The strange thing is though, when researching this, stumbled across this page that indicates the XMLHttpRequest object should follow redirects (see the comments). So it seems like this would be a non-issue.
Unless the processing page is using an HTML meta redirect (like below) to do the redirection. In that case, I'm not sure what could be done - maybe try to parse the returned HTML for meta tags and see if any of them are attempting a redirect.
<meta http-equiv="refresh" content="0;url=http://www.example.com/some-redirected-page">
You can't get the full HTTP headers from an AJAX call in JQUery, so you can't process the redirect in this way.
However with a raw javascript request you do have access to the XMLHttpRequest getAllResponseHeaders() method which will allow you to process the redirect (this function for single headers).
Sorry, not directly an answer to your question, but I'm sure it's possible with jQuery too as it's quite simple with Prototype.
// Warning: this is Prototype, not jQuery ;-)
//...
onComplete: function(response) {
var refresh = response.getResponseHeader("Refresh");
var whatever = response.getResponseHeader("Whatever");
}
//...