If I log a user in via a secure HTTPS AJAX POST, does this mean the body of the HTTP POST is encrypted and therefore secure?
It depends on what you want to protect against (what threats should be mitigated).
HTTPS is a secure channel between the client (browser in this case) and the server. This means anybody with sufficient privileges on the client, and also on the server can read the data, because those are the ends of the imaginary pipe that HTTPS is. Practically any admin on the client or on the server can read the transmitted data, but a man-in-the-middle attacker (somebody on the network inbetween) cannot, HTTPS is secure against that (and only that, albeit it's not just confidentiality that HTTPS provides, but that's a separate topic).
The more important question is, how will you put the username and password into the body of an ajax request? That would mean you had to store such username and password somewhere on the client, where it is most probably not very secure. For instance any single successful XSS attack can reveal such credentials to an attacker. That would probably be my primary concern in this case.
Related
Consider a web server (HTTP) that fetches some data from somewhere and displays it as convenient HTML to its users.
Also consider that the fetching process involves confidential data like usernames/passwords of its users. One example is our HTTP server contacting SMTP servers of popular email services such as gmail, yahoo, etc.
It would be smart to use TLS, as we don't want confidential data being exposed to men-in-the-middle.
So, the current model is:
[end user] <-TLS-> [our HTTP server] <-TLS-> [other SMTP server]
The problem here is that our HTTP server has cleartext access to the confidential data from its end users.
What would be really nice is for the end user's browser to initiate a connection to the other SMTP server directly.
The two problems are:
the browser only understands HTTP at the networking level
XMLHttpRequest normally does not allow cross-domain requests
One idea that I came up with is for the end user's browser to act like it's going to create a TLS connection to the other SMTP server, but instead of inttiating a connection to the other SMTP server, to simply send Byte-for-Byte all the data that it would send to our HTTP server instead (perhaps through WebSockets), and the HTTP server will just "proxy" the TLS encrypted data to and from the other SMTP server.
I already would know what to do on the server side, but I want to know the best practice for implementing this on the client side.
Also, does this not seem like it would be a relatively popular feature in the realm of security? The example I gave was for SMTP but it equally applies for any other protocol that can use TLS. I feel like there would be standard JavaScript methods or such.
Good Morning,
I'm developing an app in ionic and there are some $http requests(angular) that send data to a server controller(yii 1) to save data on database. I finished my app, but it doesn't have security. I was wondering how to protect it, because right now anyone if look my $http request can know what parameters have to send, and kill my app.
What I should do to protect it? Maybe through tokens? I'm really lost with security methods.
Thank you so much,
Carles.
well When you research web application security you will come across Cross-Site Request Forgery (CSRF). This attack vector is taking advantage of cookies, but in a preventable way.
Most attacks focus on stealing your cookies because nearly every website uses cookies as a form of authentication. The setup is this: when a user logs into your server, you set a cookie in the browser. This cookie contains a unique ID which is a link to the user’s session information in your database. The browser supplies this cookie on future requests, and the server knows who you are.
On the surface this sounds not-so-bad, but here is the catch: the web browser can be tricked into making requests to your server, even if the end-user didn’t perform the action themselves.
Using POST Requests
It is sometimes thought that using proper form-based POST requests will mitigate this attack, but that is not true.
Using HTTP-Only or Secure cookies
While you definitely should use these flags on your session cookie, they don’t implicitly stop the attack: the browser still sends the cookies to your domain when a request is made to your domain. Your server does not know if this is a real user or an attack.
How To Prevent CSRF
You can achieve this by relying on a set of rules that browsers respect, called the Same-Origin Policy. This policy asserts that certain sensitive operations are performed by JavaScript code that is running on our website, not some other website.
Angular packages the CSRF token approach, making it simpler for us to implement. For every request that your Angular application makes of your server, the Angular $http service will do these things automatically:
Look for a cookie named XSRF-TOKEN on the current domain.
If that cookie is found, it reads the value and adds it to the request as the X-XSRF-TOKEN header.
Thus the client-side implementation is handled for you, automatically! But this does leave the server side pieces in your hands. You will need to do the following parts:
During login: create the CSRF token (with a random, un-guessable string), and associate it with the user session. You will need to send it on the login response as the XSRF-TOKEN cookie.
Assert that all incoming requests to your API have the X-XSRF-TOKEN header, and that the value of the header is the token that is associated with the user’s session.
That’s it! With a little bit of backend work, you now have a strategy which protects you from CSRF attacks.
you will find a working example of how to prevent CSRF attack here
and for theory of understanding CSRF attacks please follow this reference
I have two web-servers responding on two different ports. I have the main web server that serves a website with a lot of javascript behind HTTP digest authentication, the secondary webserver only executes CGIs that can be directly accessed, always by using HTTP digest, or that can accessed with CORS by the ajax requests related to the main webserver. Both servers share the same users credentials.
My problem is that I don't want the browser to prompt for credentials when the javascript is making requests to the secondary webserver.
I came out with the idea that I could add some special header in the ajax request to the secondary web-server, and if this header is present I can ignore the HTTP authentication. Since the servers share the users credentials, if the user is able to log in into the main web-server, he'll be able to login into the second one as well.
Using a fixed header is of course useless. So the question is: is there a mechanism in CORS to tell the secondary webserver that the user is already authenticated in the first one? Something like a safe way to exchange tokens in cookies?
If it is only the ports that are different cookies will be shared across these origins. So if you know for sure that a cookie is set once the user accesses origin 1, they will be included in requests to origin 2, as long as (assuming you're using XMLHttpRequest) withCredentials is set to true.
Now of course those cookies should contain some authentication data that you verify before you let them bypass HTTP authentication.
And hopefully you're using HTTPS so that the credentials are safe from network attackers.
I'm not sure this has anything to do with CORS. What you need is a single-sign-on solution for the two different servers. You could implement a full-blown OAuth solution, or write a simple one yourself.
For a simple token-based authentication, you'd do the following:
When the user logs into your website, send down a expiring token (over SSL) that grants the user access to the web service.
Take the token and do a GET request to a non-authenticated endpoint in the web service. If the token is valid and non-expired, send an authentication token back to the browser.
As long as your web service implements HTTP authentication properly, the cookie will be set and the service calls won't prompt for credentials.
How I have a basic javascript registration form which sends the password that an user has filled to a secure axis2 web service (which stores the salted hash of the password in a database).
Mu question is - is there ANY WAY the password to be cracked before it's send to the server as the user enters plain text password and it's hashed on the server side.
How can I secure my javascript client and can you recommend some libraries.
Thank you in advance
The passwords are sent in plaintext, and can be easily sniffed/spoofed via man in the middle attacks like ARP posioning (in which someone on the same subnetwork as you or your client can sniff and manipulate packets).
Get an SSL certificate and enable HTTPS for your website (instructions for apache here).
For some more details on why there's no point securing stuff on the client side, see my answer here. Basically, unless there is a certificate-based trust system like in HTTPS, an attacker can always spoof whatever encryption protocol you try by modifying keys on the fly or removing the encryption code from the javascript.
Unless the connection is in HTTPS, the password is sent in plaintext. There is no client-side code that can help you with that.
If you want to protect the data transmission between the client and the server from eavesdroppers, there's a standard solution for it: SSL.
I have been reading about using a synchronizer token pattern to prevent CSRF (CSRF meaning Cross-site request forgery.), and I don't understand how it actually safe.
Let's say I have a fake bank site fakebank.com with two urls:
fakebank.com/withdrawForm.html - a GET request which displays the withdraw money form
fakebank.com/doWithdraw - POST to this url to do the withdraw
My understanding of the security flaw is that maliciousSite.com can spoof a POST request to fakebank.com/doWithdraw, and if you're currently logged in to fakebank, the POST will be successful.
Let's say we implement a Synchronizer Token Pattern which will embed a secret code on fakebank.com/withdrawForm.html. Can't maliciousSite.com just spoof a GET request for that form, parse the html result, get the token, and then create the POST request with that token?
This is assuming fakebank.com isn't checking HTTP Referrer or Origin or maliciousSite.com is successfully spoofing that the Referrer/Origin is fakebank.com.
The reason why this is secure, and maliciousSite.com cannot simply do a GET, steal the token, and then do a POST is that the request is done by the user's browser, not by the server at maliciousSite.com. All data returned from fakebank.com is returned to the user's browser, not to the server at maliciousSite.com. If maliciousSite.com does perform a GET to retrieve a token, it will be a different token than was issued to the user. maliciousSite.com cannot set this cookie into the user's browser to be submitted to fakebank.com because of same-domain restrictions.
The CSRF POST attack works by tricking the user's browser into requesting fakebank.com/withdrawForm.html directly using a properly formed POST request. The server at fakebank.com happily executes the requested POST, thus transferring funds using the parameters supplied in the POST body (which include a destination account belonging to the attacker that was put there by maliciousSite.com). The server at maliciousSite.com doesn't need to see the data returned, because the action has been taken (unless fakebank.com uses these CSRF tokens, which the maliciousSite.com can't possibly know unless it has been divulged in some way. It can't ask for it). If fakebank.com is using CSRF tokens, then maliciousSite.com will submit a POST request that is missing the token, thus indicating a potential CSRF attack in progress.
Vulnerabilities of this method include using a CSRF token that is not kept sufficiently secret and is divulged in some way. Also, if the CSRF token is not sufficiently random, then maliciousSite.com might be able to guess it. Also, if there is a weakness in the browser's enforcement of same domain policy, this could be exploited. Generally speaking, modern browsers are not vulnerable to this.
Please let me know if this is an insufficient explanation and I'll attempt to articulate it a little better for you.
And that is exactly the point. The Same Origin Policy in the browser does not allow GET requests to other sites. So no site can GET the CSRF token from another just using Javascipt within the browser.