I just found in a website what seems to be a security issue. I'm not a security expert so I would like to confirm some points before reporting the vulnerability to the website.
The website uses an "Emailed Link" for authentication. In order to receive the "Emailed Link", a user enters their email in the login form of the website. This sends the following HTTP request:
POST https://thewebsite.com/login
{
"email": "john.doe#gmail.com"
}
If the user exists in the website's database the HTTP response code is 200, otherwise the response is 404.
This makes me think of the following vulnerabilities:
The website publicly gives the possibility to check if a user exists on its database, can be brute-forced.
Anyone can spam the users of the website by sending the previous POST request.
I'd like to hear from security experts about this, should I report this issue? Is there a common name for these types of attack?
Yes, this is a vulnerability, we call this User Enumeration.
Related
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
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.
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.
There is a social networking protocol called Kopal Connect. Is this method a problem, the friend request looks like this http://alice.example.net/profile/?kopal.connect=true&kopal.subject=friendship-request&kopal.identity=http://bob.example.org/profile/, and as far as I know it can be requested for your name with an embedded image or iframe when you visit a malicious web site.
Based on the example documentation for a kopal connect friend request. I would say that this request is probably vulnerable to Cross-Site Request Forgery. However the impact is minor, its more of an annoyance users because Alice still needs to approve the friendship request. In order to carry out this CSRF attack you still need the friendship key for Alice and it maybe difficult to automate this step in the process.
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"