What are some methods that could be used to secure a login page from being able to be logged into by a remote PHP script using CURL? Checking referrer and user agent won't work since those can be set with CURL. The ideal solution would be to solve this without using a CAPTCHA, that is the point of this question to try and figure out if this is possible.
One approach is to include some JavaScript in your login form, and make it so that the form cannot possibly be successfully submitted unless that JavaScript has run. This makes your login form only usable for people with JavaScript turned on, which CURL doesn't have. If the necessary JavaScript is some kind of challenge/response that differs every time (for instance use something like http://www.ohdave.com/rsa/ to make it non-trivial), the presence of the correctly set value in the form is good evidence that JavaScript ran.
You won't be able to stop all automated scripts though, it is easy enough to write scripts that drive an actual browser engine, and they will pass this test.
There isn't any way to prevent it simply. If the script knows the user name and password they will be able to login.
You could use a captcha so that automated logins won't be able to read it, but that will be a burden on actual users as well.
If you are concerned about it being used to try and brute force a login, then you could require some additional information after several attempts.
Disable the account and require reactivation via email
Require a captcha after several unsuccessful attempts
if I undestand correctly :
you have login page what execute login script
login script is hacked by remote cURL script...
Solution
in login page place hidden element with secret unique code what can happend only once, save this secret code in session, in loging script look in session for this code, compare with what was posted to the script, should same to proceed, clear session...
more about subject: http://en.wikipedia.org/wiki/Cross-site_request_forgery
cURL is no different from any other client (e.g. a browser). You could use nonce tied to a session in a hidden input field to prevent POST requests from being made directly but there are still ways around that. It's also a good idea to limit the number of log in attempts per minute to make brute-force attacks more difficult if that's what you're worried about.
Related
I want to use post to update a database and don't want people doing it manually, i.e., it should only be possible through AJAX in a client. Is there some well known cryptographic trick to use in this scenario?
Say I'm issuing a GET request to insert a new user into my database at site.com/adduser/<userid>. Someone could overpopulate my database by issuing fake requests.
There is no way to avoid forged requests in this case, as the client browser already has everything necessary to make the request; it is only a matter of some debugging for a malicious user to figure out how to make arbitrary requests to your backend, and probably even using your own code to make it easier. You don't need "cryptographic tricks", you need only obfuscation, and that will only make forging a bit inconvenient, but still not impossible.
It can be achieved.
Whenever you render a page which is supposed to make such request. Generate a random token and store it in session (for authenticated user) or database (in case this request is publicly allowed).
and instead of calling site.com/adduser/<userid> call site.com/adduser/<userid>/<token>
whenever you receive such request if the token is valid or not (from session or database)
In case token is correct, process the request and remove used token from session / db
In case token is incorrect, reject the request.
I don't really need to restrict access to the server (although that would be great), I'm looking for a cryptographic trick that would allow the server to know when things are coming from the app and not forged by the user using a sniffed token.
You cannot do this. It's almost one of the fundamental problems with client/server applications. Here's why it doesn't work: Say you had a way for your client app to authenticate itself to the server - whether it's a secret password or some other method. The information that the app needs is necessarily accessible to the app (the password is hidden in there somewhere, or whatever). But because it runs on the user's computer, that means they also have access to this information: All they need is to look at the source, or the binary, or the network traffic between your app and the server, and eventually they will figure out the mechanism by which your app authenticates, and replicate it. Maybe they'll even copy it. Maybe they'll write a clever hack to make your app do the heavy lifting (You can always just send fake user input to the app). But no matter how, they've got all the information required, and there is no way to stop them from having it that wouldn't also stop your app from having it.
Prevent Direct Access To File Called By ajax Function seems to address the question.
You can (among other solutions, I'm sure)...
use session management (log in to create a session);
send a unique key to the client which needs to be returned before it expires (can't
be re-used, and can't be stored for use later on);
and/or set headers as in the linked answer.
But anything can be spoofed if people try hard enough. The only completely secure system is one which no-one can access at all.
This is the same problem as CSRF - and the solution is the same: use a token in the AJAX request which you've perviously stored eslewhere (or can regenerate, e.g. by encrypting the parameters using the sessin id as a key). Chriss Shiflett has some sensible notes on this, and there's an OWASP project for detecting CSRF with PHP
This is some authorization issue: only authorized requests should result in the creation of a new user. So when receiving such a request, your sever needs to check whether it’s from a client that is authorized to create new users.
Now the main issue is how to decide what request is authorized. In most cases, this is done via user roles and/or some ticketing system. With user roles, you’ll have additional problems to solve like user identification and user authentication. But if that is already solved, you can easily map the users onto roles like Alice is an admin and Bob is a regular user and only admins are authorized to create new users.
It works like any other web page: login authentication, check the referrer.
The solution is adding the bold line to ajax requests. Also you should look to basic authentication, this will not be the only protector. You can catch the incomes with these code from your ajax page
Ajax Call
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP Requested Page Answer
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}
I am using a simple PHP API that takes requests and connects to a MySQL DB to store/retrieve user information. Example: Login is done using a HTTP POST to the API with username and password.
How do I prevent people from flooding my API with requests, potentially making thousands of accounts in a few seconds.
Thanks
You could serve a token generated and remembered on the server side which is rendered with your forms and validated when the form is sent back to your server. That prevents the user from just generating new post requests without actually requesting the according form from your server since they need the according token generated on your server to get it through.
Then there is the mentioned captcha which would be way too much for a login form from my point but when it comes to things like registering a new user the captcha in combination with the token sounds very good to me.
UPDATE
I Just found this article which is about floot protection of script execution in general. I think their approach is good as is the ip tracking provided you have the ability to use memcache or something similar to speed the checks up.
First, when registering a user, also save her IP address at the time of registration in the DB.
If the IP already exists within 45 minutes of previous registration, reject the request.
Another method is the Captcha, I personally prefer a different method that I found to be even more effective against robots.
Instead of asking the user to "type what they see in an image", and verify they are humans (or robots with sophisticated image processing),
Add another field (for example city), and make it hidden with javascript.
The robots would submit that field to the server, and humans would not.
Note that the robots must run the javascript in order to know what fields are hidden, and this is a time consuming process that they usually don't do.
(see turing halting problem)
i've a jquery script which post/get data to .php script. but i wanna prevent direct access to the php script. for example if the user look at the html source code,they will be able to access the php script directly by copying the url from the js file and i dont want that. how do i prevent users from doing that?? i want the user to use it via the html UI. i've google but found no link on this. however, i did notice that some popular websites are able to do that. how should i go about doing this??
It seems like a simple redirect is what you're looking for here.
Add something like this to the top of your php file. This will prevent the page from being accessed if the proper post has not been made. Of course you'll have to change the post and redirect to content more relevant to your project.
if (!isset($_POST['data'])) {
header('Location: your-redirect-location');
}
You may also be able to redirect based on the $_SERVER['HTTP_REFERER'] variable.
EDIT: I was going to explain this in a comment but it's too long. I should note that this is a simple solution. It will keep people from accidentally accessing your script. It's really difficult to create a 100% secure solution for your issue, and if somebody really wants to access it, they will be able to. If you don't have anything secure in the script in question, this will be fine. Otherwise, you'll have to look for an alternative.
Here is one solution:
<?php
if(isset($_POST["post_var]))
{
//to the code you want to do when the post is made
}
else
{
//do what you want to do when the user views the post page
}
?>
how do i prevent users from doing that?
You can't - all you can do is mitigate the risk people can fiddle with your script. Making sure you have the right HTTP_REFERER and/or POST data are both useful in that regard: a "malicious" user would need more than pointing her browser to the URL.
More techniques can be used here:
using session variables: you might not want users that are not logged in - if applicable - to use the URL.
using a one-time challenge (token): you can place a value in the HTML page and have the JS code send this value along with the POST request. You store this value in the session when it is generated. Checking the POSTed token against the session token guarantees the user has at least "seen" the HTML page before submitting data - this can also be useful to prevent duplicate submissions.
However, remember that anything a browser can do, people can do it as well. All these techniques can prevent the curious from doing harm, but not the malicious.
All you can do is making sure nobody can really harm you, and in this regard, your Ajax URL is no different than any other URL of your site: if it's publicly reachable, it has to be secured using whatever technique you already use elsewhere - sessions, user rights, etc.
After all, why should you care that users use this URL not using a browser ? You might want to think of it in terms of an API call that, incidentally, your page happens to use.
Your problem is similar to and has the same problems as a cross site request forgery.
To reduce your risk, you can check the request method, check the referrer, and check the origin if set. The best way is to have a secret token that was generated on the server that the client transmits back in every request. Since you're dealing with friendly users who have access to your live code, they may be able to debug the script and find the value, but it would only be for one session and would be a real hassle.
iam using ajax for sending requests to one of my php pages in the site... but i do this from my html page. This is secure....
But what if others know my php page and they send ajax requests to that page from their script? This may cause any security problems.
How can i avoid this ?
You seem to be trying to defend against CSRF attacks.
You can include a nonce in your page, then require that all AJAX requests have that nonce.
Since the attacker is on a different domain, he will have no way of getting the nonce.
The only way they can send AJAX requests to your page is if they are on the same domain (ie. their script would have to be hosted on your domain).
AJAX won't work cross-domain, so it's quite secure.
There is very little you can do to stop this, the only think that can help prevent this is by having a good application architecture.
For example, the following rules will help:
Try and keep your Ajax down to read only.
If you have to use Ajax to write then you should follow these rules
Only allow users that are logged in to submit data
Validate Validate & Validate your post data, Make sure its exactly as you expect it
Implement a form hashing technique that generates a unique hash for every form on every page, and validate against a variable within the session Aka (Nonce)
If the user is logged in make sure there's a validation period, such as "You must wait 30 seconds before posting".
Always use session_regenerate_id() before you call session_start
These are just a few pointers that should get you on your way, when researching these you will come across other techniques used by other site owners but you should always remember the following 2 rules.
Never trust your users, just act like you do
Whitelist and never blacklist.
Almost everything is in the title :
Here's what I'd like to do :
A nice html page with a php authentication process (http first then https & so on)
Launch a flex app which knows (I don't know how (this is the actual question !)) the user has already been authenticated and display his/her stuff he/she has to do for the day (or whatever...).
Of course if someone try to call directly the flex app I would display an "authentication error" message and then redirect to the authentication page.
I'm sorry for my English which is perfectible.
I was thinking about the session cookie : first authenticate then ass a variable on the server side, something like :
$_SESSION['authenticate']=true
Then, on the flex side, just send the cookie and ask if the user is properly authenticated, something like calling a php web page like :
https://is_authenticated.php?php_session=xxxx
Thank you
Olivier
What are you using on the server side? Remember that you shouldn't do anything in the flex application other then send the SESSION ID along with any requests. Any time where the client checks security, you have a bug. The server must validate the session and determine if the request is allowed.
It sounded in your last comment that you are worried about people manually calling a web page. Each page must check to see if the user is authenticated. I don't know your specific application, but you may try looking at AMFPHP and see how they do session authentication. Good luck!
Your on the right track!
You could use session-authentication, these links might help you out:
http://www.zend.com/zend/spotlight/sessionauth7may.php
http://www.tizag.com/phpT/phpsessions.php
There is also the possibility to use http-authentication
http://se2.php.net/features.http-auth
however http-authentication is not as flexible as session-authentication, and also means some more configuration on the serverside.I would therefore recommend you to stick with sessions.
This is exactly what I would do.. A few things to consider from a security standpoint:
If your php service (from flex) gets an unknown session token, always generate a new one. This also applies to your PHP application and is often overlooked.
I would generate the swf with javascript, and manually insert the session cookie using javascript. This way people won't download and safe (or cache) your php pages with sessions that are invalid in the future.
Even better would be to use a separate token other than the session, and on the server figure out what the session id was based on this flex token.