PHP Security - How does Facebook block login from other hosts? - security

I search alot about this topic but I didn't found any useful solutions.
How does Facebook detect that the host isn't Facebook even if the referrer and host can be faked in the request headers using curl or an HTML form in another website.
If you send the login POST parameters to https://m.facebook.com/login/ , Facebook will display a message : (For security reasons, don't login from website other than Facebook) and they block the login.
So how they can 100% sure that the request is made from Facebook.com?
Thank you.

They probably use a version of CSRF. Looking at the actual login form, there are 14 (fourteen!) hidden HTML fields in addition to the username and password. At least 4 of them look to me like a CSRF token. You would need to pull them all out of the home page and send them in with your login request. Tools like curl can send such a complete request, but you will still need to retrieve all the fields yourself.
CSRF is a way of preventing (or at least making very very difficult) a website from being POSTed to from a page not on its own website. The usual way of implementing it is to create a one-time-use token, store it sever-side in the session and also put it on the web page. If the HTTP POST omits the token, then the POST is not accepted. Reload the page with the form and the token is re-generated. Some sites have an expiry for the token, too - that is, it will only work for a short time, such as 10 minutes.
BTW, this has nothing to do with PHP. CSRF support is in many many frameworks in many languages and it's not difficult to build it yourself.

Related

CSRF Requesting the nonce makes malicious POST possible?

I am trying to wrap my head around csrf protection and there is something I have trouble understanding. Maybe someone can give me the insight I need :).
What I understand
Say we have no csrf protection. Someone logs in to a website A with his/her credentials. After valid login a session cookie is stored in the browser. The user POSTS some data through a form and the sever accepts it with no trouble. Since we have no csrf protection this opens the system up for a vulnerability.
The user visits another website B, a malicious website like a phishing attempt. This website is posting to website A in the background with some javascript xhr request for example. The browser has the cookie stored for website A and since the user was logged in already this is a valid session. Therefore website A will accept the post without any trouble.
To solve this csrf protection comes in. Upon loading the page with the form on website A from the server a nonce (one time code) is generated. This code must be submitted with the form so the server can check if this post came from the same session that requested the form. If the code is the same as the one that was just generated the form is accepted. If the code is missing or incorrect, the server says no.
Question
If malicious website B first makes a get request to the page that renders the form. It would be able to fetch the token to send along with the post request afterwards. Right? Am I missing something obvious?
Thanks!
I understand that you concern is that a malicious website can request your anti-CSRF token.
You would need to prevent cross-origin reads or embedding of pages or endpoints that returns the CSRF tokens. One of the important things to keep in mind is that CORS don't provide CSRF protection, as preflight CORS requests are not always executed by the browser, for example when using regular html forms.
Most modern browsers block cross origin requests by default. When you do need cross origin requests for your own domains, can you do that by setting the correct Cross Origin headers, like Access-Control-Allow-Origin: sub.domain.com.
To prevent embedding in an iframe you can implement the X-Frame-Options: to DENY, or SAMEORIGIN.
You can find more information on https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

Session and cookies from cross site

I have a front end HTML website that posts requests to a WebApp hosting online. These html pages run locally on any machine. Thus, they are making cross site requests.
I am thinking of saving cookies and validating these cookies in each request that is sent to my WebApp. Is that the best way to go?
Also, when the user goes back and forth from 1 page to another, (and it is required that he is logged in), do i send a request with cookie from the HTML at the start of the page and redirect him to login page accordingly if his cookie is not valid?
Thanks in advance,
The way you are planning to go about seems alright. Ofcourse you will have to think well about how you are going to save your access tokens. I would use an access token with the IP, username and session expiration date encoded in it.
However just checking on page load would not be the best idea since the result of the check could be spoofed. You should sent this acces token with every request for information so your webapp can decide wether or not to reply with information.

How to enforce same origin policy in Express.js?

Suppose I have the following URL route:
app.post('upvote', function(req, res) {
// make a database a call to increase vote count
});
What can I do to prevent others from opening up a console and sending AJAX POST request on www.mysite.com/upvote? I'd like it so that only www.mysite.com is allowed to make that POST request and no one else.
What can I do to prevent others from opening up a console and sending AJAX POST request
Who is "others"?
If others==users of the site... there is nothing you can do to stop them sending whatever requests they like, using the JavaScript console or any other means. You can't trust the client, so you have to have server-side authorisation: requiring that the user be logged into an account, and registering that the account has upvoted so can't vote again.
If others==admins of other sites (by serving script to their users that causes submissions to your site)... it isn't possible for JavaScript on another site to cause an AJAX POST request, or at least not unless you deliberately opt into that using CORS. But it's quite possible for them to cause a POST by simply creating a <form> pointing to your address and submitting it.
This is a classic Cross Site Request Forgery problem. The widely-accepted solution to XSRF issues is to include a secret token as a parameter in each POST (form or AJAX) submission. That secret token is associated with the logged-in state of the user, either by being stored in the server-side session, or replicated in a client-side cookie. Either way an attacker from another site isn't capable of getting hold of a token that is valid for the logged-in user, so they can't fake the request.
You need XSRF protection on all actions that have a direct effect, whether AJAX or form-based POSTs.
I agree with bobince. others is a very general term.
If others belong to other sites (malicious sites on net).
express has csrf middleware to protect from Cross Site Request
Forgery. You can use it to prevent such a scenario. See the API docs
here.
If others are users of your own site
then that is an authentication issue. Every request must be
checked before serving / executing it. You should implement a user
authentication to prevent this situation. I use passport, and
ensure that user is authenticated before I actually run app.post
handler.

lwIP on Stellaris 32-bit microcontroller - Secure Login

I wish to use my Stellaris LM3S8962 microcontroller as a bridge between internet and a bunch of sensors. I will be using Zigbee nodes for communication from the sensors to the microcontroller. I have been able to use the lwIP TCP/IP stack (for LM3S8962) to access HTML pages stored in the controller's flash.
Now, I want to add a secure login system for the same. What I basically want is that - when I enter the IP of the controller in the browser, it should prompt me for a username and a password. I want to make this system as secure as possible using the lwIP TCP/IP stack.
FYI, the stack does not support PHP or any other scripts. CGI feature (in C) is supported but I don't know how to implement the security part. Please guide.
There are basically two ways you could implement user authentication over HTTP on your platform:
"classic" Basic HTTP authentication (see RFC2616 for exact specification),
a login form, creating a session ID, and returning that to the browser, to be stored either in a cookie, or in the URL.
Basic HTTP authentication works by you inserting a check into your web page serving routine, to see if there is an Authorization HTTP header. If there is, you should decode it (see the RFC), and check the specified username/password. If the credentials are ok, then proceed with the web page serving. If the credentials are incorrect, or in case there is no Authorization header, you should return a 401 error code. The browser will then prompt the user for the credentials. This solution is rather simple, and you'll get the browser login dialog, not a nice HTML page. Also, the microcontroller will have to check the credentials for every page request.
Authentication via a login form works by your server maintaining a list of properly authenticated user sessions (probably in memory), and checking the request against this list. Upon loggin in, a unique, random ID should be generated for that session, and the session data should be entered into your list. The new session ID should be returned to the browser to be included in upcoming HTTP requests. You may choose the session ID to be put into a browser cookie, or you can embed it into the URL, as a URL parameter (?id=xxxxx). The URL parameter is embedded by sending a 302 Redirection response to the browser with the new URL. If you want the cookie solution, you can send the response to the login request with a Set-Cookie HTTP response header. In the login form solution, the actual credentials (username/password) are only checked once, at login. After that, only the session ID is checked against the list of active sessions. The session ID has to be extracted from the requests for every web page serving (from the URL, or from the Cookie HTTP header). Also, you'll have to implement some kind of session timeout, both as a security measure, and to put bounds to the size of the list of active sessions.
Now comes the harder part: in both solutions, the username/password travels in some requests (in every request for the Basic HTTP authentication, and in the login page POST for the login form solution), and can be extracted from the network traffic. Also, information neccessary to hijack the session is present in every request in both solutions. If this is a problem (the system works on a freely accessible LAN segment, or over network links beyond your control), you'll probably need SSL to hide these sensitive data. How to get a reasonable SSL implementation for your platform, that's another question.

What are the security concerns with redirecting a user after login to a url supplied in the login form?

I have a members area on my site where if a user is not logged in, they are redirected to the login url with ?redirect=[CURRENT_URL] and they are redirected back to [CURRENT_URL] once they successfully login.
What are the potential security issues with this approach, how to prevent them and what are the alternatives?
e.g. a malicious user can link to my site with a redirect link to another site, would that other site be able to steal my user's login cookie? Is it possible to run arbitrary javascript on my site with this approach?
If current url is not redacted, you can be subject to
XSS (stealing cookies, injecting
scripts)
Response Header Splitting
etc
If you know current URL is a constant and has NO parameters, it's not as risky. As soon as you add parameters or make the url based on user input, trickiness ensues.
A trivial example of XSS:
Say your url can have a query string injected via user input. Then
what stops them from saying
redirectUrl="yoursite.jsp?somevariable="alert('malware')");
or
redirectUrl="yoursite.jsp?somevariable="alert(document.cookies)");
And stealing your cookies or executing other evil java script.
Response splitting is more complicated. Basically if you can inject a CRLF you can do some very whacky things.
Wikipedia has a decent explanation of this vulnerability - there are others you can find by googling for http response splitting.
I've left out the most obvious attack which is if the user can control the url they can go to a site that LOOKS like yours and convince the user to enter credit cards, credentials etc. Eg if you are a bank, and someone can inject
redirectURL="http://myfakebank.com"
and copies your page, gosh, the user will happily say "Sure, I'll reeenter my credentials"

Resources