So when an event takes place in the client browser, it sends a log request to the server. I wanna get the timestamp of the event as close to real as possible. However, we discovered we cannot trust getting this from Javascript because some browsers have bogus times, like this morning a browser sent us a timestamp from sometime in the year 2000.
The next best thing would be to get the time the request was initiated. Right now we have the timestamp set to be the time the request was received, since we can only trust the server.
I need the timestamp to be trustworthy and as close to the time of the creation of the HTTP request as possible.
Server runs on PHP 5.3.3. Thanks
As Jon told, you cannot trust client inputs. If the difference between request creation on client side and request receiving at your side is so vital for you, you can try to adjust your timestamp using netspeed databases (for example, https://www.maxmind.com/en/netspeed)
All this should already be logged for you in the apache or ngninx access.log. You may need to enable it, but that is your easiest option. If you insist on making a php log, simply do the following:
<?php
file_put_contents("mylog.log",new DateTime() . " - {$_SERVER['REMOTE_ADDR']} visited.\n");
?>
somewhere within the page you want to log. You will have to add some unique identifier though, perhaps IP address or some session ID or something.
OK well I realize the solution based on all the feedback is just to stick with what I have, which is logging the timestamp from when the request reached the server. This is as close to the actual event as you can get and still have a trustworthy timestamp.
Insert in the form
<input type='hidden' name='reqTimeStamp' value='<?php echo time();?>'>
Related
Imagine the next scenario: a user wants to register to a webpage and fills a form. While he is filling the form, jQuery keeps checking through a regular expression if fields are valid, etc...
Taking the email as the primary key which the user will use after registering to login, the email field needs to be checked with Ajax to let the user know if that email is registered or not. I want to check it with Ajax to avoid sending the full form and emptying it, refreshing page, etc...
So, when the user has ended filling the email field, the Ajax request is sent to the server, something like the next link:
example.com/check.php?email=abcdefg#gmail.com
When check.php receives the email, it asks the database if it exists or not and returns a message like: User already exists if user exists or null if user does not exist.
The question is: if someone digs through my .js and finds out links similar to that, they could use that link to send a large number of requests to find out if those random emails exist. This could lead to heavy use of the database or in the worst cases even crashing and private information leaks.
Someone could do a huge for loop to check emails like:
//Getting the response of the next links
example.com/check.php?email=aaaaaaa#gmail.com // Returns null
example.com/check.php?email=aaaaaab#gmail.com // Returns null
example.com/check.php?email=aaaaaac#gmail.com // Returns null
example.com/check.php?email=aaaaaad#gmail.com // Returns User already exists
------------------------------------------------------------------------------------------------------------------------------------
Since i last accepted the answer, i kept investigating this and found the solution to avoid this behaviour. The following code is for JAVA but the logic can be applied to any other server-side language.
Before doing ANY ajax request to the server, I request a token to the server. This token looks like this fmf5p81m6e56n4va3nkfu2ns8n it is made by a simple method, it can, however, be more complex, but this is good to go.
public String getToken() throws UnsupportedEncodingException {
return new BigInteger(130, new SecureRandom()).toString(32);
}
When requesting the token, the server does not only return the token, but also a small script that in case someone uses browser to inspect element (and browser navbar) and such the script will run and the token will be cleared. Servlet returns something like this:
_html += "<head>"
+ "<script> "
+ "window.onload=function(){\n"
+ " document.body.innerHTML = \"\";\n"
+ " }"
+ "window.location.href='http://mywebsite.com' "
+ "</script>"
+ "</head>"
+ "<body>"
+ "[" + token+ "]"
+ "</body>"
+ "</html>";
First empties the body then navigates back to wherever we want. javascript/jquery will however, catch the entire content as string, then I simply extract the string between [ and ]. This token is only available for the next request, so every AJAX request will have its unique token. On the 2nd reques the token just used is deleted.
After I get the token I append it as parameter to whatever link i request, something like this:
ajaxRequestObjet = $.ajax({
url: "http://localhost:8084/mywebsite.com/servlet", //<-- local tomcat server
method: "POST",
data: "type=AJAX&page=some-article&token=fmf5p81m6e56n4va3nkfu2ns8n"
});
This method works fine against someone who inspects the website manually and try to use the links, but what about java/php/IIS servers that do this automaticly?
For this ask for header! Something like this:
boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
It will be true only and only if XMLHttpRequest exists....
There is one last thing to keep in mind. Make sure 'Access-Control-Allow-Origin' header is NOT present in your app to make sure that any javascript NOT in your server wont get the server resources. If this header does not exist, chrome will return this:
XMLHttpRequest cannot load http://localhost:8084/mywebsite.com/servlet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Java server was in tomcat and I had another apache for this tests, this is the small html present in apache which gave the error above:
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
ajaxRequestObjet = $.ajax({
url: "http://localhost:8084/mywebsite.com/servlet",
method: "POST",
data: "type=AJAX&page=Token"
});
ajaxRequestObjet.done(function (msg) {
alert(msg);
});
</script>
</head>
<body>
</body>
</html>
While you can not control this 100%... there are a few options..
Try using the same methods that people use with Captcha scripts..
Basically when the user loads the form / page.. You generate a random string/id in their PHP session and store it.. When they send the ajax requests, have your ajax check also append the string/id and require it before allowing a check to perform else return a header of 500 or something..
Using this approach with sessions, you could set a allowed limit of checks (say 5) and once the user has tried more than 5 checks, They are required to reload the page or perform a human check (eg Captcha).. Then it resets their count.. Even allow a total of say 30 within 1 hour / per IP or something.
Also use smart events to trigger when the ajax check is done, eg field/tab change or on a button press.. Or when a valid email is detected.. but say .com.au would trigger twice.
Basically this way, even if someone sniffed your JS files and tried to automate the email checker.. It would require them finding a way to append the string/id that you generate and also limit their amount of requests performed.
Beyond this, there is not to much more you can do easily.. But there are still a few other idea's.
Most of them would work around using a PHP session / cookie.. Say for example if they check and find 3 email addresses.. Then again you set that as a limit and force them to require a manual submission or something.
See how the above suggestion goes for you, any questions do feel free to ask. But may take me a day or two to reply as weekend.. Also research how Captcha scripts work as plenty of source code for them.. As they work on the same idea.
Time Delays will simply look bad / make your site appear slow / bug the user with waiting for a response.
You need to limit the amount of look up's per session / ip address.. Otherwise there is always a way to get past these checks.. Basically once they hit a limit.. Force the user/ip/session to wait a few minutes/hours and verify them with a Captcha script so it can not be scripted...
Javascript Security / Hiding The Source
While you can not do this truly, you can do certain things generate the JS using a PHP page with a JS header.. so <script src='myjscode.php'></script> and this allows PHP to check for a valid session.. So stops external requests to an extent.. But this is mostly useful for allowing JS to be only available behind a membership/login..
Multiple Checks / If Possible In This Case
Depending on your approach, is this for a user to check if they already have an account? If so.. you could combine the email check with something like their name/country/age/dob ... So they would need to select two or three correct matching values before being able to get a check/response from the ajax call?
Maybe not in your case, but just thought would add this as well.
The JavaScript code on your website is executed on the computer of the user, so there is no way you could stop him from digging through your code. Even if you use a code obfuscator (for example, https://www.javascriptobfuscator.com/), the hacker could debug your application and record all requests send to the server.
Everything security-relevant has to happen on the server. You could limit the amount of requests from a specific IP address.
You could protect against brute force attacks with something similar to CSRF tokens:
Assign a server-generated ID to every client session. Each request to check.php should include this ID.
check.php should reject requests that do not include an ID, or include an ID that the server did not generate (to prevent attacks with spoofed IDs). It should also rate limit on ID - if a given ID has made a request in (say) the last second, or a given ID makes more than n requests in a 10 second interval, it should return an error response. This protects against requests from a single session arriving from several IP addresses.
You should also rate limit by IP address to prevent brute-forcing by opening a large number of web application sessions.
There isn't much you can do to prevent an attacker looking up a single, or small number, of specific email addresses - it's an inherent risk with this type of validation.
One approach to resolve this problem could be this:
Suppose you have ajax request calling your server to receive a response from a particular user or client. You can have a table in your database where you provide a unique token for every user or hash value that can be checked every time user makes an ajax request to the server. If the token value matches the user request value than he is a genuine user. You can also record his number of request on the table to ensure he is making legitimate requests. I acknowledge the fact that it may slow down your app performance, but it will be safe option to consider. Note: you need to retrieve the token on your HTML page to send it with ajax.
Please comment to know more. I have been using this approach and there is no problem until now.
Example:
This type of attack can be treated the same as any other brute force attack, where the only effective solution is to use a Captcha. But of course, Captchas are a detriment to UX, so you have to consider if the additional security is worth it, especially for an attack that is very unlikely to happen anyway. That said, you may want to use a Captcha on your registration form anyway, to prevent bots from creating accounts.
This sort of attack has a huge cost for little reward for the attacker. There are billions of possible email addresses to test for. It could only be worth going to great lengths such as this, if the site in question was particularly sensitive, such as some kind of adult site, where the attacker hopes to blackmail users that he finds.
CloudFlare
Not as good as a Captcha solution but the brute force attack might be detected and prevented by CloudFlare's DDoS system. Also, CF can force Tor users to solve a Captcha before accessing your site, which would prevent an attacker from using Tor as a vehicle for the attack.
IP Rate Limiting
Rate limiting on an IP basis has problems because if an attacker decided to undertake a task as huge as this, he will likely be using a Botnet or some other system of multiple machines to launch the attack.
Consider a large organisation such as a University, where all users share the public IP. One of the users launches an attack on your site, and you block his IP, and in the processes blocking everyone else. This countermeasure could actually be used to launch a DoS attack.
Session ID/CRSF Token
Definitely not a solution because the attacker needs to simply make a request to the page first, to obtain the token. It's an additional request to make but only an inconvenience for the attacker.
First of all: I'd URL-encode the mail-address. 'example.com/check.php?email=' . urlencode(abcdefg#gmail.com)
Ad your question: when check.php is called, you can
check, if the user's session and his IP have sent a request during the last seconds
if not, write the user's session, the user's IP plus the current timestamp to a helper-table plus to a cookie and hit your DB
if yes, block the request
But I'm afraid this won't help you from fraud because everyone can check your JavaScript and if someone want's to exploit this, he will find ways.
check.php should depending on the setup either only be accessible internally, or verify from where the connection is made. Take a look at this previous question- I hope it might be what you're looking for. how to verify the requesting server in php?
You could use a CSRF token and exit early from your script if you detect that no or an invalid CSRF token. Almost (if not all) PHP frameworks come with support for this.
Also check this question from the security community: https://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token
I want to build an application which will automatically broadcast notification(s) to a user when data on server is changed. So far, I just know one method of doing this i.e. using JQuery setInterval. Using this function, every client requests data through ajax to server, asking if something changed.
The weakness of this method is every client must send a packet every specific time interval, so my server receives huge data packet. It's so frustrating to manage the server. Are there any alternatives for this besides Jquery setInterval?
If Websockets is not an option for you, you could use one ajax request to the server. Than server side go into a infinite loop. Use the sleep function to not overload the memory. Than check each time if there is something changed. If so, break out the loop and return the data. On the client side send immediately the next request.
After a bit of research it's called "Ajax long-polling requests".
Here is a explanation.
The PHP code would look something like this:
$prevHash = $_GET['hash'];
while(true){
$currHash = GetHashFromTable('myTable');
if ($prevHash != $currRowCount) break;
sleep(3);
}
$response[0] = GetDataFromTable('myTable');
$response[1] = GetHashFromTable('myTable');
echo json_encode($response);
Update
Long polling is not the best option. Better to use web-sockets.
If you want to compare the differences, see this answer: https://stackoverflow.com/a/10029326/3269816
I just discovered a bug which I couldn't find any solution of, I would like your advise on that. Issue is there are a few hidden input types, which are there to store ID's of already saved data such as per person id if it is already saved etc. etc.
I just tried and change the value of that hidden variable manually, using google chrome and submit the form and surprisingly i did not get the id that should be there but instead i received the Id that I changed. for instance there was an value of 22 I change it 263 I received 263, whereas I should have be receiving 22. I want that 22 to come not that 263.
Its hard to explain I know but I have tried my level best to convey my issue please help and advise my on that how should I store some hidden value that are un-editable.
Any Idea?
Rule of Web Development #1: Never trust the client
Rule of Web Development #2: Never trust the client
Rule of Web Development #3: You can't make the client trustworthy
If the user shouldn't be able to edit it, never give it to them.
As others have said, there are a few ways to handle the situation. The most common is to use a SESSION variable on the server, available almost everywhere.
Store the "secret" values on the SESSION. They will be available when the user posts back.
You cannot control what data users put in HTTP requests to your server.
Instead, use authentication and authorization, on the server, when the request is received, to make sure that the user is allowed to submit the values they submit.
If you're wanting to keep track of data from one page to another I would use sessions. This is data that is tracked on the server.
//page one.php
$_SESSION['id'] = 22;
//page two.php
echo $_SESSION['id']; //22
This is a basic functionality of how browsers work - essentially someone could POST data pretending to be your form with whatever values they wanted in the fields - or even add extra fields.
If it's a problem consider moving that data from hidden fields to session variables.
If it's important for your hidden fields to be secure, don't contain them on the client-side. Client side variables are pretty easy to modify.
You should probably store them in your session, so they're not outputted to the client. If they're required on the page, use AJAX to grab them instead.
It kinda depends on the domain of your application, if it's in-house software then I wouldn't worry about it particularly.
It does not look like a bug.
What scares you about this? These fields are not going to be accessed and changed by your visitors. If you're afraid someone is going to hack the http request of your visitor and change his order (for example), then https connection should help.
I'm making a php mailer which gets POST data from a javascript application xmlhttp request.
It works fine with about 50 contacts but I just tested it on 150 test email addresses and mid way through the script hit the max execution time (because I put a delay after sending each mail) and then it automatically restarted the script with the same data and started sending mail from the first contact onwards.
I was worried it was going to loop indefinately, but it stopped after hitting the max exec time in the second run. I closed the javascript application during the second run, so maybe that had something to do with it stopping.
I'm going to either increase the max execution time or parse the php chunks of data instead, but I need to make sure that this can never happen again because in a real world run I can never have two emails sent to the same person.
Is there any other case where the php script might run twice and is there a sure fire way to ensure it can never happen?
If you read mails from file you need cut them off from it or make list with sended mails and compare with source list.
Moreover would be better to use database with columns like id,target,sent(true/false),datetime and update it after mail successful sends
I am assuming your e-mail addresses are in some sort of database, making the answer fairly straightforward.
Add another common of DATETIME to your table, and update it every time the scripts sends an e-mail to that contact.
Right before you send the email, get that stamp and compare it to a human value, DATETIME of previous and current message. If the last message was sent after the most recent was issued, don't send it.
If I was wrong in assuming there is no database.... I highly suggest you get a database.
I want to store some variable to the client side, currently, I have few selection (javascript variable, cookie, session), because I want to reduce the workload from the server, so the incoming parameter will not check on the server side.
For example,
Client side
<div id="showmoney"></div>
<script>
var money=10000;
$('#showmoney').html(money);
function changemoney()
{
{ pass the variable 'money' by ajax to php...}
}
</script>
PHP side
<?
$money = $_POST['money'];
$sql = "UPDATE user_details SET money = ".$money." WHERE uid = 123";
{ do query...}
?>
Are there any method make it more secure, because I afraid someone can modify the javascript variable by tools(firebug? if yes, how?)
thanks a lot~:)
Every variable that you do not want the user to change (such as a price tag) HAS to be stored on the server and not on the client. There are A LOT of ways to change what the client sends to you, and FireBug is just the simplest tool. More sophisticated tools will allow to intercept and edit every HTTP request..
Are there any method make it more secure, because I afraid someone can modify the javascript variable by tools(firebug? if yes, how?)
You can never, ever trust incoming data from the client. It can always be manipulated. Essential checks like prices you need to do on server side - a client side check is merely for the user's convenience.
Also, the code you show has a SQL injection vulnerability that you should sort out.
Anything you store in the client (browser) can be manipulated. The fix for your issue, is to verify that the information sent back to the server hasn't been tampered.
People can do just about anything to the page they want.
In the Google Chrome debugger (accessed with Ctrl+Shif+J) they could do the following in the console:
money = 10000000000000; //Or whatever arbitrary value they choose
changemoney();
As other people have said, never trust anything that people pass into the server from the client. The server needs to do a sanity check.
you have to align your desire to store something on the client for performance with the need for security. Sensitive info should only be on the server. Any savvy web user can tweak the javascript. Save bandwidth by putting other, less sensitive info on the client.
are you know about client side database storage the brand new API in HTML5. trying to find sollution with them. maybe helpful for you to save some data on client side.