Only allow specific referrer PHP - javascript

I have this code in my website
<?php
// This is to check if the request is coming from a specific domain
$ref = $_SERVER['payskip.org'];
$refData = parse_url($ref);
if($refData['host'] !== 'payskip.org') {
// Output string and stop execution
die("Hotlinking not permitted");
}
echo "Executing code here";
?>
and it does what it should do, if you visit the site without the given referrer it will show "Hotlinking not permitted", but if you visit it from payskip.org it will execute the given code.
So far so good, but if I refresh my page with f5 or the reload button it executes the code again! I want it to execute only once and if you refresh it should go back with the hotlink is not permitted.

Well, what your server needs is a way to remember the visitor. You could do this via many ways but let me state the two most common:
1. Sessions
2. Database.
If you are only interested in stopping the 'refresh browser' hack, using sessions should solve your problem but what happens when the same user visits your site some other time after the session must have ended?... In such a scenario, you might want to also remember such a user...and that's where database comes to the rescue.

Related

$_SESSION empty when POSTing to different page [duplicate]

Exactly when and where should I use session_start() in PHP?
For example, say I have a login script that sets a session variable to tell whether or not the user is logged in. Must I then put the session_start() at the top of the script, or only right before I actually set the session variable if the login was successful?
<?php
// session_start(); here?
if (login($username, $password)) {
// session_start(); or here?
$_SESSION["username"] = $username;
}
?>
Another case is this, according to w3schools
Note: The session_start() function must be the very first thing in your document. Before any HTML tags.
As others have said, the absolute requirements of what you must do are:
You must run session_start before you read or write to $_SESSION (otherwise it will just be an ordinary array and not saved anywhere).
You must not run session_start twice during a single script execution (page load) unless you use session_write_close to close it in between.
There is an extra rule that technically has exceptions, but is best treated as absolute:
Do not start the session after you have written any output (echo, HTML outside PHP blocks, etc), because PHP may not be able to send cookies to the browser if the server has already started sending the content.
There are two reasons you might want to avoid starting the session:
PHP locks the session when you open it to avoid two processes writing conflicting data into it, so if you have several requests happening at once, you want to avoid them waiting for each other unless they really need to. For instance, if you're responding to an AJAX request, and don't need any data from the session, don't open it.
As mentioned by symcbean, there is some cost to creating a new session, so if your site is busy with either legitimate or malicious traffic, you might want to serve some landing pages or error messages without starting it at all.
After that, it becomes a matter of style and architecture, but the rule of thumb that covers most of the above is "as soon as possible, if you're sure the page needs it".
Unless you have output buffering enabled, the session_start() must come before anything other than headers are sent to the browser (as it sets a cookie in the header).
It must come before you attempt to reference the $_SESSION data.
In your example there are no html tags being output before either instance - so both would work.
There some cost to opening a session, so if you are doing additional, non-session based validation of the request, then deferring session_start() till these checks have passed does give you a bit more resillience against DOS attacks.
Starting the session at the top of the page is most of the times the best. But if you don't need the session for the whole document/code, you could always put it, as in this example, after the if() clause.
The session_start() function can go anywhere in your code. You should just place it at the beginning of your document for consistency and call it a day. If you have a separate database or config file you are including on all your login/database driven pages, you should place it in there so you don't have to recode it into every page.

How to set offline a User in the DB when it closes the browser?

i have a logout function that sets the User offline in my DB (mysql), but if it just closes the browser, in my DB the User is still online despite it's not , How can i manage this? How can i set the User Offline without press the logout botton? Cheers in advance !
Ps: Yes, i'm using SESSION
You can do it in following ways.
1) send the Ajax request to server every 5 seconds to update the current time.
2) and where you want to show offline just get records where current time is more than 5 seconds ago.
HI the only reliable way is to set an interval that calls the server and logs it in a database
var timeout = 15000; //milliseconds
setInterval( function(){
$.post('yoursite/keepalive' );
}, timeout );
Then you check the session on the server side you need a simple database table with the user id and a timestamp of the last time keepalive was called, then you just get the current time an there id ( from the session ) and save that. Then you can check if its been more then say like 20 seconds you will know they are gone ( should be updated every 15 sec ). Obviously you would need to have this interval on every page of your site to accurately track a user.
Things such as checking the session time, and unload are not accurate enough,
Unload is fired when any page is closed, so for example,
we have a user that has 2 pages open, they close one of them. the other page is already loaded so there is no traffic between client and server, and no way to know that page is still open
for Session time we have a similar problem, say someone is reading a long post on your page, They need to use the facilities and leave the page open. 30 minutes go by the come back and continue reading the post for another 10 minutes. now maybe the session has expired maybe it hasn't the fact remains they are still looking at your site, and you have no way to know it.
An interval will continue as long as the page is open and there are no javascript issues. A disadvantage of this is it will also keep their session updated ( you can get around this by sending the user id along with the ajax and not using the session, but that has other complications ) because you have that 15 second update you can check anytime if it has been more then 15 seconds. Say you want to display a list of online users to your other forum users, you just query for everyone with a current timestamp from that table, easy beazy.
As for the amount of time for the interval, you have to strike a balance between performance ( network traffic ) and how granular you need to know the information, if it's ok to only know if they logged off within the last minute then use that, if you can wait 5 minutes to know etc....
Really the Crux of the problem is how the server, and a client communicate. Right there is no two way communication like if your on the phone. It's more like a walkies talky where you have to say 10-4 and let go of the button for the other guy to talk. Essentially a client will make a request, that request is fulfilled by the server. that is the end of the communication and the state. Subsequent request state is maintained by using session so the next request uses that session to 'remember' the client. other then that there is no communication between client and server. There is no way to know they hung up the phone, for example, but to ask them if they are still there. ( this is an oversimplification because you cant send a request from the server to ask, more like they have to tell you they are not there, unless you use node.js or something like that ).
As #David has mentioned you could track this based on last activity, for that you would just need to know when the session was last updated. One of the easiest ways is to move the session into a database handler via http://php.net/manual/en/function.session-set-save-handler.php that way you can access when they were last active.
Using this vs ajax really depends on what you need to know, and how accurately. There is also the content of your page to weigh in. If you have a site that makes requests frequently it would be a better approach because you save on network traffic, for example. However, if you have long post someone could be reading for 20-30 minutes but want to know more frequent then that use ajax.
You can do it in many ways:
Launch an AJAX call on onbeforeunload javascript event. Prompting for a confirmation "Windows is closing, are you sure? YES/NO" should give you enough time to set the flag in the db, just be sure that if the user clicks "NO" you should unset your flag
Check session time... Add a var in your PHP_SESSION that is updated at every user event. If it becomes older than a preset threshold (i.e. 5 minutes), you can safely assume the user is gone
Example for onbeforeunload
function myConfirmation() {
return 'Are you sure you want to quit?';
}
window.onbeforeunload = myConfirmation;
You can try the javascript beforeunload event:
window.onbeforeunload = function() {
// Some AJAX request to logout.php or whatever script handles the logout
}
It will trigger when the user attempts to close the current window.
Watch out though, even if the user closes a single tab (your page), the event will be triggered, so if there are other tabs opened, so the browser will be, and you'll still get your users logged out.
Also, if several tabs of your website are opened, and you close one of them, you'll get your users logged out, which may not be what you want, so you'll probably have to find a way around to fix it.

How to append to form "Thanks for the email!" after submit button is pressed?

I'm building a contact form for my website and I would like users to enter their information, click submit, have the information process with php and to just have a message display on the bottom of the form. Originally, I was redirecting to another page and the form was working properly, but now I just want to append a small message and can't get it to work.
This is what I have currently in my contactengine.php file for it to process all the variables and send the email.
if ($success){
THIS IS WHAT I DID BEFORE THAT WORKED BUT HAS TO REDIRECT
// print "<meta http-equiv=\"refresh\" content=\"0;URL=index_thanks.html\">"; //
//BELOW IS WHAT I WANT TO OCCUR
<script type="text/javascript">
$("#contact-area").append("Thanks for your message!")
</script>
}
You don't need JavaScript for this. JavaScript is great, but it should only be used where necessary, since it can add some brittleness to the user experience.
Here's a possible design approach:
Set up a POST form
Process the form, set a session variable to thank the user, and redirect to the form again. This switches the browser from POST to GET mode†, and is usually as simple as this:
header('Location: http://yourdomain.com/form.php');
exit();
Render the form as usual. If a session variable is set to thank the user, render the thank you message, and unset the session variable‡
I wouldn't use a <meta /> refresh here - it needs to load more data to work, and is more fiddly to implement.
† The POST-redirect approach is a common design pattern in web development. There are plenty of resources about this on the web, if you are unfamiliar with it. It fixes problems associated with rendering web content inside a POST method, particularly in relation to page refreshing and using the back/forward buttons.
‡ These temporary session variables are sometimes known as flash variables. They exist from one HTTP operation to the next, and are erased at the end of the second operation.
You cannot put JavaScript inside of your PHP code. However, I will give you an explanation of what you need to do.
On the client side, bind an event for the click, then
$('form button').click(function() {
$.post('file.php', {'object': 'property'}, function(success) {
if(success) {
$("#contact-area").append("Thanks for your message!")
}
});
});
On the server side, you will process this:
//file.php
$sentByAJAX = $_POST['object'];
return true;

Remove POST data when using custom javascript back button

I've coded some custom navigation buttons into the project I'm working on, via javascript - they essentially copy the browser button functionality (brief wasn't initially clear on why separate buttons were required, but they asked for them):
function goBack() { window.history.back(); }
function goForward() { window.history.forward(); }
However, as the functionality is the same as the browser back button, the website asks if I want to resubmit POST data if I go back to a page with said POST data, which is undesirable. Ideally, to fit with the current site setup (all POSTs submit to the originating page, which checks for POST data and performs the relevant submissions to the database), I want to clear the POST data so there is no request to resubmit.
I'm not familiar with the Post/Redirect/Get (PRG) that people might recommend, and it doesn't seem to cover the concept of continually pressing "back"; if you submit a form, you post to a page which handles the post action, then redirects to a GET page - but the redirect is still in the history, meaning if you go back, surely you would hit the redirect page and just be sent "forward"? Plus, PRG seems mostly centred on page refreshing, which is not what I'm looking for at the moment.
The concept of PRG also seems to be due to the browser back button not allowing for additional code to control POST data, so coders have to make the best of what they can access.
With my relative freedom of having a custom back button which could allow for manipulation of POST/session/cookie data, I'd consider there should be some method of calling a global session variable or cookie on back button press, which then gets picked up on the previous page load to unset the POST data and the global session variable/cookie, but my attempts to implement something like this have not succeeded - they've been simple single-line setcookie('back', true) or set($_SESSION['back']=true) PHP snippets within goBack(), with PHP earlier in the page:
<?php if (isset([either set cookie or set session variable]) {
unset([either set cookie or set session variable]); // also tried changing 'true' to 'false' here
unset($_POST);
}?>
Is this kind of behaviour possible and I'm just looking at this from the wrong angle, or is the only way to do a successful back action while suppressing POST to re-engineer the site to use PRG, which will be comparatively significant legwork? Is there some other point in a page load/POST submit that would allow for clearing the POST data, to allow for the back button functionality I'm looking for?
EDIT
I, as an example, navigate to site.com/stuff/edit/[an ID], to edit an item of stuff. The first time I visit, there is no POST data, so the PHP check of isset($_POST) returns false and the page is simply rendered with a form which is populated by a GET.
I amend in the form and press submit. The submit sends the POST data to the target page; this is STILL site.com/stuff/edit/[an ID]! However, because there is now POST data, the PHP picks this up, validates it on the page (you'll see why later) and performs backend model and controller functions to update the item to the database serving the site.
Depending on whether the update was successful, the page then renders the form again, with the information which is retrieved from a GET, which pulls the information from the server (amended or otherwise) and either a success or fail message.
If I want to add a new item, I navigate to site.com/stuff/new; this navigates to the same page as site.com/stuff/edit, but PHP code determines the masking URL and renders different aspects of the code to look like a different page with a different POST action - it also notes there is no ID passed in.
I add an item, and the POST redirects back to the same page; this time, though, there is no Id from the server, meaning the code behind picks up the fact it is a new entry, and performs an insert. It then either displays a success message with a link to view/edit the new item, or a failure message with a prepopulated form to reduce retyping the new item into the form.
I hope this has helped show how this page works; its not necessarily how I would have written the site, but I've inherited the work from an ongoing situation and work with others who code in this way, so I need to be consistent or make unobtrusive changes rather than radical redesigns of in-use code.
I think this should do the job:
function goBack() {
var referrer = document.referrer;
if(referrer != '') {
window.location = referrer;
} else {
window.history.back();
}
}

Is Go back safe?

I have a link like the one in the title in a custom 404 error page, which allows the user to go to the previous page just like with the browser's go back button. I just wanna ask if this method of linking is safe or not. I guess it is safe, but I am not sure. Thanks in regards!
One use case I can say that will not be "safe" is if the user has JavaScript disabled. In that case, you would have to create the link dynamically with server-side code using the HTTP referer header field's value as your href value on the anchor element.
Another thing to consider is the never-ending back and forth loop users would get stuck in, if they came from a page with an HTTP redirect.
Edit:
As you said above, you can use $_SERVER['HTTP_REFERER'] but the documentation says
.. This is set by the user agent. Not all user agents will set this,
and some provide the ability to modify HTTP_REFERER as a feature. In
short, it cannot really be trusted.
In reality, most browsers do set it correctly though, and seeing how this is not mission critical I think it's safe if you use it. You could also account for browsers that don't set it as follows:
if(isset($_SERVER['HTTP_REFERER']))
{
// Show a Back button link, if the referrer is available
echo "« Back";
}
else
{
// If not, show a link to your homepage instead
echo "Home";
}

Categories