Maybe it is incorrect, but this is not a tutorial or something, its a question. So if it is incorrect, please correct it.
Situation:
Sending data from client side to server side using GET / POST / PUT / DELETE.
**
Here there is just another AJAX request as described above using the POST method with jQuery and AngularJS:
$.ajax({
type: "POST",
headers: {
"Content-Type": "application/json"
},
url: "https://www.myawesomedomainname.com",
data: JSON.stringify($scope.fetchData),
success: function(response) {
// some code
},
error: function(err) {
// some code
}
});
The security problem:
One can use the same Internet Wifi and since the data is not ecrypted, one can see the data transferred to the server. This security issue called: "Man in the middle".
The solution:
Working with HTTPS to encrypt the transferred data from client side to server side, will let the man in the middle see just bla bla bla.
The problem:
If we want the described above to work, both client side and server side have to know the encryption keys, otherwise, the targeted server will get the data encrypted too (like the man in the middle).
Not everytime we have that privilege - sometimes the client side does not own any kind of domain - maybe it is a mobile application?
The question:
When I am sending, lets say, from cordova mobile app, data to server side, which the server side has HTTPS url, does it securely encrypted and prevents man in the middle attacks?
When using HTTPS the entire request including other than the host address in the URL is encrypted. That includes the query string and server path.
Essentially MiTM attacks are prevented with only a very small attack surface by a very sophisticated and dedicated network attacker or an attacker that has physical access to the client device such as the device owner. That can be closed by pinning the certificate. This is generally not required.
Pinning the certificate means the client verifying that the certificate is the correct server certificate by comparing all or a portion of the certificate against compiled-in information. Many networking APIs contain pinning support.
Related
I have a fairly basic query that I hope somebody can help with.
A website www.example.com presents a form to the user which collects a bunch of personal data. e.g. name, email, telephone.
The full URL is http://www.example.com/
On submit the form's data is collected via JavaScript, POSTed via an AJAX call to www.example.com/process.php and passed to the server via a secure API call using a curl request.
The full url provided in the curl request is https://api.mysecuresite.com/
Do I need to provide an SSL certificate for www.example.com?
Yes.
The data could be intercepted between the browser and http://www.example.com/process.php.
(Consider an analogy: You take a large amount of cash out of the bank, hold it up in the air and walk two blocks down the street. Then you put the cash in an armored van. Is this is safe way to handle the cash?)
Also: A man-in-the-middle attack could inject a script into http://www.example.com before it gets put into the HTTP request to http://www.example.com/process.php. This could also intercept the data even if you were making the Ajax request directly to https://api.mysecuresite.com/.
Additionally, users will be informed that http://www.example.com is insecure, which will (correctly) discourage them from trusting any assurances you make that their data is safe.
I want to login to a website and follow redirection whit ajax or XMLHttpRequest or any thing else exept php.
Actually whene i try to do it, i have error "302 Moved Temporarily" but the webpage is the right page so i don't know why i get this error.
The website is an external website (not on my server).
This is my code :
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded",
url: "http://website/index.php",
data: { username: "myuser", password: "123456" },
success: function(data) {
console.log("success ", data.response);
},
error: function(data) {
console.log("error ", data.error);
},
dataType: "html"
});
If you try use ajax outside your domain, you will probably get this error message:
XMLHttpRequest cannot load http://www.example.com/path/filename. Origin
null is not allowed by Access-Control-Allow-Origin.
The reason you get this error message is because of the Same-origin policy. The policy permits scripts running on pages originating from the same site to access each other's data with no specific restrictions, but prevents scripts access to data that is stored on a different domain.
This could be a problem if you are trying to access publicly hosted data, but there are ways around it.
Here is the list of methods:
Implement CORS (Cross-Origin Resource Sharing)
Use JSONP (JSON Padding)
Use postMessage method
Setting up a local proxy
CORS (Cross-Origin Resource Sharing)
CORS is a mechanism that allows resources on a web page to be requested from another domain outside the domain the resource originated from. In particular, JavaScript's AJAX calls can use the XMLHttpRequest mechanism. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request. It is more useful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.
JSONP (JSON Padding)
JSONP or "JSON with padding" is a communication technique used in JavaScript programs running in web browsers to request data from a server in a different domain, something prohibited by typical web browsers because of the same-origin policy. JSONP takes advantage of the fact that browsers do not enforce the same-origin policy on <script> tags.
Because of the same origin policy, we can not make cross domain AJAX requests, but we can have <script> tags that load javascript files from other domains. JSONP uses this exception in order to make cross domain requests by dynamically creating a <script> tag with necessary URL.
postMessage method
window.postMessage method is part of HTML5 introductions. It allows communication between window frames without being subject to same origin policy. Using postMessage() one can trigger a message event with attached data on another window, even if the window has different domain, port or a protocol. The frame where the event is triggered must add an event listener in order to be able to respond.
Let's see an example. Assume, we are on http://example.com (1) website and would like to make a request to http://example2.net (2) domain. We first must obtain a reference to (2) window. This can be either iframe.contentWindow, window.open, or window.frames[]. For our case it's best to create a hidden iframe element and send messages to it.
Setup local proxy
This method overcomes same origin policy by proxying content on another domain through itself. Thus making cross-domain issue irrelevant. To use this method you will either a) setup your server as a reverse proxy to fetch content from another server or b) write a script that would do that.
This cross domain querying solution works because you actually loading content from your own domain. You request the URL and the proxy script on your server loads the content and passes it over to you.
http://www.ajax-cross-origin.com/how.html You can visit this link if you want to learn about these methods in details. There is also a jquery plugin named ajax cross origin to tackle similar issues.
I've an API endpoint hosted (built via Django Rest Framework), for eg:- domain.com/api/fetch_all?start=0&end=50. This fetches all the results from the database in a pagination manner.
Now I'm representing this information on a webpage. Its more or less like an open forum where everyone can read the data, but only some can write. I'm viewing this data onto the webpage via an AJAX request hitting the above endpoint. For eg:-
$.ajax({
type:'get',
contentType: 'application/json',
url:'domain.com/api/fetch_all?start=0&end=50',
cache : true,
dataType:'json',
success:function(data)
{
// presenting the information when the page loads.
}
});
So, my questing is how can I secure my APIs, so that no robots can access the data that I'm presenting on my forum. For eg:- if any code/script tries to access my APIs, it should throw 403 Forbidden error.
import requests
# this should return 403 error
response = requests.get('domain.com/api/fetch_all?start=0&end=50')
However, if I try to get this data via the browser AJAX request, it should return the data. How can I make sure whether the request is coming from a browser(man-handled) or a robot?
PS: I cannot add OAuth functionality over here, since I dont have a login form.
It's not possible to restrict requesters in this way, because a robot could always add headers to spoof being a browser. Anything you do on your client can be copied by an attacker. Without requiring auth, the best you can do is rate limiting - track requests on a per-client basis, and only allow a certain number of requests per time unit.
A partially-functional solution would be to look at the User-Agent header. That should include browser information, and might let you knock out some robots, but not all or even most of them.
Is it ok to pass passwords like this or should the method be POST or does it not matter?
xmlhttp.open("GET","pas123",true);
xmlhttp.send();
Additional info: I'm building this using a local virtual web server so I don't think I'll have https until I put upfront some money on a real web server :-)
EDIT: According to Gumo's link encodeURIComponent should be used. Should I do xmlhttp.send(encodeURIComponent(password)) or would this cause errors in the password matching?
Post them via HTTPS than you don't need to matter about that ;)
But note that you need that the page which sends that data must be accessed with https too due the same origin policy.
About your money limentation you can use self signed certificates or you can use a certificate from https://startssl.com/ where you can get certificates for free.
All HTTP requests are sent as text, so the particulars of whether it's a GET or POST or PUT... don't really matter. What matters for security in transmission is that you send it via SSL (and handle it safely on the other end, of course).
You can use a self-signed cert until something better is made available. It will be a special hell later if you don't design with https in mind now :)
It shouldn't matter, the main reason for not using GET on conventional web forms is the fact that the details are visible in the address bar, which isn't an issue when using AJAX.
All HTTP requests (GET/POST/ect) are sent in plain text so could be obtained using network tracing software (e.g. Wireshark) to protect against this you will need to use HTTPS
Following on from the thread
Is Safari on iOS 6 caching $.ajax results?
If io6 safari is caching the results from non unique ajax calls then it must also be caching the call itself. Would this then mean it is caching usernames and passwords in a login situation thereby posing a security risk?
Short version: If you're sending usernames and passwords over the wire in plaintext, you've already opened a huge security hole.
Long version: Browsers will cache based on URI, so if you're sending user/pass as GET variables, then yes it will cache and yes it is a security risk. However, even if the browser didn't cache this, you're still doing something wrong. A third party need only look at the HTTP header to see what the user/pass is.
If you are sending this as POST, it is a bit harder to find the username/password. The browser will not cache the request as the URL is always the same. However, it is still possible to read the content of the request and find the user/pass.
To be the most secure, use HTTPS and pass the values via POST. The entire HTTP request is encrypted, including the headers. However, the browser will still cache the URL, so using GET variables is still a bad idea.
Example from the jQuery documentation on using POST with ajax:
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});