Run PHP code on Window / Tab close with Javascript - javascript

I need to run this code:
<?PHP
$pin=$_GET["pin"];
unlink("../users/$pin/host.php");
unlink("../users/$pin/votes.php");
unlink("../users/$pin/guest.php");
rmdir("../users/$pin");
echo "Session ended";
?>
Which is located at php/endsesh.php
Basically, when you start a session it creates you a folder with a pin number, and it places a host, guest and votes file.
I need this PHP script to run when the tab is closed, so it can delete all those files (Otherwise I'm just overloading my server with files)
So far I'm trying this with no luck:
<script>
window.onbeforeunload = function() {
alert("<?php include("http://musicdemo.hol.es/php/endsesh.php?pin=" . $_GET["pin"]; ?>");
$.get("http://musicdemo.hol.es/php/endsesh.php?pin=<?php echo $_GET["pin"]; ?>");
return false;
return "If you exit this page your session will not end. Please either allow the pop-up, by staying in this page and closing again, or click the link saying 'Close this session'";
}
</script>
neither the alert or the $.get commands work.

onbeforeunload is a highly secured, sandboxed event. It's really designed solely to catch people with "are you sure you want to close this window" messages, so I'm pretty sure it doesn't allow more advanced features such as an ajax call. To do so would open up security holes that allow malicious sites to prevent you from closing the window.
I think doing an ajax call to clean up server side session files is not the appropriate strategy anyway, since the browser could easily crash, laptop could lose power, user could lose network connectivity preventing the ajax call etc. You can't rely on that ajax call succeeding.
PHP already has very good session handling capabilities via session_start() and the $_SESSION global variable, which already has a built in cleanup feature for expiring old sessions.
If you absolutely must keep your current solution, what I would do is run a cron job every hour, day, week, whatever, that searches for any of your files that haven't been accessed in say 24 hours and deletes them.
Also I should note that taking a $_GET and passing it directly to unlink is one of the worst, most insecure things you can do in php. If you have that running on a server right now, you need to fix it immediately, since a malicious user could potentially do something like http://musicdemo.hol.es/php/endsesh.php?pin=../../../../../../etc/passwd. if 'pin' is a number, you should at least do something like:
<?PHP
$pin=$_GET["pin"];
$pin = (int) $pin; // ensure pin is converted to an integer
unlink("../users/$pin/host.php");
unlink("../users/$pin/votes.php");
unlink("../users/$pin/guest.php");
rmdir("../users/$pin");
echo "Session ended";
?>

This code looks to be incorrect, try:
<script>
window.onbeforeunload = function() {
$.get("http://musicdemo.hol.es/php/endsesh.php?pin=<?php echo $_GET["pin"]?>");
return false;
return "If you exit this page your session will not end. Please either allow the pop-up, by staying in this page and closing again, or click the link saying 'Close this session'";
}
</script>
It looks like your alert line is messing this up.

remove alert().
keep $.get.
Have you seen the apache logs?
Probably you could have a permission problems (chmod +x endsesh.php).
I think i will give a try with exec (http://it2.php.net/function.exec).
But before you have to understand if endsesh.php is reached.

Related

Iframe shows authorized users

I created an "embed code" within my site, which is simply an iframe
I would give this code to embed only certain users but do not know how to do. a user could get inspecting the html code from the authorized sites and get the code without permission.
how do I make my site that only authorized users?
I thought about taking $ _SERVER ['HTTP_REFERER'] but as soon as you click a link to the internal frame the referrer is lost.
You can't really avoid authorized person inspecting the URL of the inline frame and revealing it to an unauthorized person. The right course of action is to serve an empty/error page to an unauthorized user.
You could achieve that by creating a session upon user login and verifying that session in the source code the of page displayed in the inline frame.
Do not rely on referrer, it is easily spoofable and some browsers won't even set it. Session cookie is not spoofable unless the user knows the credentials used to create it, which makes them authorized, whether or not they are authenticated.
Verify the user with js.
<iframe src="verify.php">...
Verify.php contains:
<?php
session_start();
$id= generate sth random;
$_SESSION["id"]=$id;
?>
<script>
window.location="http:yourdomain/site.php?id=<?php echo $id;?>&referrer="+document.referrer;
</script>
Loading...
Now you can check the referrer, to verify if the site is correct and the id to check if nobody tried to trick you...
<?php
session_start();
if($_SESSION["id"]!=$_GET["id"] or $$_GET["referrer"]!="allowedsite.com"){
echo "not valid";
die();
}
?>
As Thomas Hübelbauer noted, people could still copy your code. The only thing you can do against it is obfuscation and the use of relative links. That makes it hard to copy.

Clickable html button counter using php or js

I am very new to php and javascript and I was wondering how I could make a global counter that adds 1 to it every time a user presses a button. The number would stay the same even if someone is on a different computer or refreshes the page. I had this using javascript:
<script type="text/javascript">
var clicks = 0
function onClick() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks;
};
</script>
<button type="button" onClick="onClick()">Click me</button>
<footer>Clicks: <a id="clicks">0</a></footer>
But when ever someone refreshes the page, it resets the number, and it is not global. I tried making something in php which is:
<?php
$clicks = 0
public function clickButton()
{
$clicks = $clicks + 1
}
?>
but I have no idea what I'm doing and how to call the php function or display the php variable.
Your current problem is that your Click variable is only storred on the one computer clicking.
You need to do 2 things:
Store the click variable.
Read the click variable.
(Live updates.)
Store the click variable:
As Vinicius Maia said you need a connection between the users and this can be done with a database, read about MySQL.
Or you can use a more simple method and use php to read and create / write the Click variable into a file named Clicks.txt. See PHP Filesystem Functions on W3C
Read the click variable:
If you chose the MySQL method you should use the commands as so, else if you chose the primitive method you can use the following command: Php File Get Content
Live updates:
To show the variable live and not making your users refresh you should be able to use AJAX so make sure to take a look at that. This question might be usefull.
You should make a interval loop which should constantly check for updates in the variable. This question might be usefull
Together:
Take a good look at Jonas w's answer, he gives a good example on how you could make this and he follows your request. Only downside by using this tactic is that everytime you click you refresh, which might be annoying for some users.
But what he does is:
He reads the variable.
When you click the button he runs the PHP code by opening it.
When done with the code he send you back to index and refresh the side
Repeat...
But for your users, maybe you should add the live function by using this system:
Read the variable.
Make a loop with AJAX that calls a php function that checks and return updates
When you click the button use AJAX to run another php function to update the variable
Repeat...
You have the right JavaScript logic, now you just need to store your clicks somewhere that won't be affected by a browser refresh!
My first suggestion would be to utilize HTML5's localStorage object.
The examples are pretty good on the link. See if you can make something work!
Javascript or PHP will not solve your problem. Just because what you need is some connection between all users that will access your website. For that, you must use some kind of database. I recommend you starting learning MySQL.
Check this: http://php.net/manual/en/book.mysqli.php
The php variables just work inside of one request. So if two people request your site, the script runs twice in two different versions. You have to store the variable on the server.
You could store it into a mysql database ( good articles about that on php.net)
or you could make a counter.txt and edit it with php. ("Fopen" on php.net)
The php runs on the server and cannot interact with the clients side js. You need to send this "button click" to the server. You can do this with AJAX ( google that) or reloading the site and passing gets and posts to the server
Update.php:
<?php
$file=fopen("counter.txt","c+");//open or create counter.txt
$counter=fread($file, 10);//read content
$counter=(int)$counter+1;//add one
fwrite($file,$counter);//save counter
fclose($file);//close file
Header("Location: index.php");//go back to index.php
?>
Index.php:
<?php
$file=fopen("counter.txt","c+");
$counter=fread($file, 10);
fclose($file);
Echo $counter;
?>
Click me
if you need that different users see the same counter, then you will need save the counter in a database.
Regards.

repopulating $_POST variables transparently in PHP

So.
In a LAMP stack (PHP), I've got this situation where I'm showing an intermediate page based on some variable from the first page --more simply, I have one page called, say, ListOfProjects, from which I can select a project to view.
When I go to that project, there are other page-navigation elements (like looking at individual jobs in the project, say) the user can click. Once I click them, and am navigated away from the intermediate page between ListOfProjects and IndividualJob, I have to resubmit the data that got me there.
That's fine, and if I could do it automatically, I would. However, I haven't found a way to force this behavior and eliminate the extra click and the ugly "Confirm Form Resubmission" screen.
Does anyone know a way I could A) silently force form-resubmission when the user hits the back button or B) avoid the situation where there's a form that needs resubmitting?
I've thought about trying to just pass that project ID to the session variable, but it's well within scope to have more than one individual project open in the same browser, which would make that unwieldy.
Thoughts? Suggestions?
Thanks!
Don't use POST.
When you are getting data from the server, use GET and put the data in the query string.
POST is designed for sending data to the server that will make a change (e.g. updating data in the database), it isn't appropriate for just deciding what data to look at.
Some solution is bypass using jQuery to resubmit a form when click on back:
<?php if (isset($_POST['ListOfProject'])): ?>
<form method="POST" id="backToProject"></form>
<script>$("#backToProject").submit()</script>
<?php endif ?>
Another solution is to use header("Location: ...") to force users to redirect a page, BUT you should remove all previous $_POST request using unset($_POST) such as:
unset($_POST);
header("Location: your_uri://your_path");
Try reload a page and reload a page using javascript into <script> tag such as:
if ($_POST['ListOfProject'])
{
echo '<script type="text/javascript">location.reload();</script>';
}
Try to understand GET/POST method: https://en.wikipedia.org/wiki/Post/Redirect/Get
And I don't recommended using link of sites using $_POST method such as say Quentin user.

Are JS variables secure from user manipulation?

I am trying to separate an tangled mess of PHP and JS. I'm not looking for perfection in the first draft but anything is better than the current state.
Current (all in one file):
<?php if( checkSecureUserStuff ): ?>
//bunch of js like including admin features
//not fun stuff
<?php endif; ?>
Proposed:
PHP file
if( checkSecureUserStuff ){
$userAccess = 'admin';
}
...
//Later in file, I know this still not ideal
<script>
var useraccess = <?= json_encode($userAccess) ?>;
</script>
JS file
if( useraccess == 'admin' ){
// do the admin related JS stuff here
}
Obviously in the final HTML var useraccess = 'admin'; will be visible. Is it open to manipulation at that point? I know this design isn't great, but is it terribly insecure?
Oh yea, I should mention. Actions are still checked on the server. This is more about securing the UI and keeping certain stuff disabled. The server would still verify actions.
I guess the question is more about can a user manipulate the UI if the variables are set and checked on document load. Already partially answered by millerbr's mention of setting break points
. Didn't think of that
Yes. The user will be able to open their browser console, view the code, pause it at a breakpoint they have set, and then write code in the console to edit the variable.
You should never trust your frontend for security type things - yes, write code to limit access, but always double-check on your backend and assume any requests are insecure.
There are things you can do to obscure your code and make it more difficult to manipulate, such as minifying the code, but nothing is 100% effective and so you should always assume the frontend is compromised and place the necessary precautions on any incoming data or requests.

Check if user closed the page in PHP?

I made a chat using PHP and JavaScript chat and there is a disconnect button which removes user from the chat removing him from user list first. But if the user closes browser then he will remain in the user list. How do I check if he left?
This must be done without putting any handles on page closing in JS because if user kills the browser then he will remain in chat.
By the way , JS script always sends a request to the PHP page which constantly checks for new messages in a loop and when there are some, the script prints them out and exits. Then it repeats all over again.
EDIT : How do I make a heartbeat thing in PHP? If a user closes the page the script execution will be terminated therefore we won't be able to check if the user is still connected in the same script.
Sorry, there is no reliable way of doing this, that's the way HTTP was built - it's a "pull" protocol.
The only solution I can think of is that "valid" and logged in clients must query the server in a very small interval. If they don't, they're logged out.
you could send a tiny ajax call to your server every 5 seconds. and users that doesn't do this aren't in the room any more
You answered your own question: if you don't detect a request for new messages from a user over a given length of time (more than a few seconds), then they left the room.
The nature of HTTP dictates that you need to do some AJAX type of communication. If you don't want to listen for the "give me more messages" request (not sure why you wouldn't want to), then build in a heartbeat type communication.
If you can't modify the JS code for some reason, there really is little you can do. Only thing you can do with PHP is to check if there's been for example over 15 minutes from the last activity, the user has left. But this is in no way a smart thing to do – a user might just sit and watch the conversation for 15 minutes.
Only proper way to do is using AJAX polling in set intervals if you want to do it reliably.
You noted that a user polls the server for new messages constantly, can't you use that to detect if user has left?
Maintain a list of active users on the server, as well as the last time they connected to the chat to request new messages.
When a user connects to check for messages update their time.
Whenever your code runs iterate through this list and remove users who haven't connected in too long.
The only failure is that if the number of users in the channel drops to zero, the server wont notice until someone comes back.
To address your edit, you can ignore client termination by using ignore_user_abort.
Using javascript u can do the following :
<script type="text/javascript">
window.onunload = unloadPage;
function unloadPage()
{
alert("unload event detected!");
}
</script>
Make the necessary ajax call on the unloadPage() function to ur PHP Script
Request a PHP script that goes a little something like this, with AJAX:
register_shutdown_function("disconnect_current_user");
header('Content-type: multipart/x-mixed-replace; boundary="pulse"');
while(true) {
echo "--pulse\r\n.\r\n";
sleep(2);
}
This way, you won't constantly be opening/closing connections.
The answers to all the questions asked by the OP are covered in the section in the manual about connection handling:
http://uk3.php.net/manual/en/features.connection-handling.php
No Ajax.
No Javascript.
No keep alives.
C.

Categories

Resources