PHP Beginner Security Fear - php

I'm a tech writer who has done a lot of HTML/CSS but have been thrown into a pressure cooker to rewrite a web app in PHP and have done fairly well, but I'm a bit concerned re the security.
Specifically, the main page is INDEX.PHP, where the user logs in. Once they are logged in, the page rewrites portions of itself and shows menu options not available to users who aren't logged in. About 50% of the users will never need to login since they'll be viewing public documents for which no security is needed. The other 50% of users will have restricted viewing access to certain documents/pages and be able to write to a database.
I got all of this working fine, but am concerned about two things I'm doing and whether they're proper:
A logged-in user might get redirected to another page, say PAGE1.PHP. I don't want them to be able to save the URL for PAGE1.PHP and just go directly there, bypassing security, so on PAGE1.PHP I have a check for a log-in cookie I created on INDEX.PHP. If the cookie exists they can go to the page, if not they can't. Is this the right way to do this type of thing?
How do I stop a malicious user from inserting a redirect into one of the many text boxes on my various forms? I need to allow HTML, such as strong, font, background, etc. I've been running all the text box values through a function that checks for possible malicious things, one at a time, such as "meta http" or "anchors" or "java script" but I'm not sure this is the best solution.
Thanks for your help!

$_SESSION will be your friend. In a normal shared-hosting environment, $_SESSION may not last any longer than, uh, the current session so plan accordingly. (IE, don't rely on it for anything more than logging in.)
You'll need to read up on session_start and friends.
In addition, check out this discussion: PHP HTML sanitizer for sanitizing HTML input. (Just as an FYI, there is a reason why bbcode and markdown are so popular.)

No - every client can manipulate his cookies and send everything they want - even a invalid "login" Cookie. You have to store those Information serverside in sessions
You could use strip_tags to only allow some Special tags or use a html sanitizer

1 . Upon successful login, store a new $_SESSION variable, say, the user ID (since that seems to be needed often)
Example:
if(login is successful)
{
$_SESSION['userId'] = $userId;
}
Create a php auth page that checks to make sure the session var is populated. If not, redirect to access denied or login page.
Example:
if(! isset($_SESSION['userId']) || $_SESSION['userId'] == '')
{
header("Location: accessDenied.php?msg=Not logged in");
}
On each secure page, require('auth.php');
2 . You can use strip_tags on the textbox, and mysqli_real_escape_string on user-input that ends up going to the database. (Or use prepared statements, see Best way to prevent SQL Injection in PHP)

Related

Where is the correct place to call session_start()?

There seem to be two principle ways of setting out a login system with PHP from the code I have studied as a beginner. I would like to know which is the "better" way to do it.
The first way calls session_start() in the header of every page, regardless of whether the user is logged in or not. The login script when called adds variables via $_SESSION. If the variables match the Users table then the user is logged in and gains access to the login area.
The second way first calls session_start() in the login script, and then in every further page within the user area.
Given that session_start() needs to be called to create or resume sessions, is best practice simply to put it in the header and forget about it?
OR
Should session_start() be called for the first time in the login script?
What are the implications of this decision?
The first way calls session_start() in the header of every page, regardless of whether the user is logged in or not.
This is ideally the best option for a number of reasons.
Maybe additional functionality can be added for security (or other reasons) from the very start. For example, maybe you could have some blocked IP addresses which you do not want to access your website, or you could use the session for gaining statistics.
So maybe you want to see where a person was redirected from to get to a certain page, even when they are not logged in.
Overall it helps to develop easier session management for security reasons and develop statistic functions.

How to allow a user to log into a website and save their username information in PHP/HTML?

I am trying to create a website where a user logs in or creates a new account if they are not already a user. I have that working, but what I cannot seem to figure out is how to have PHP or HTML save the username through different pages. A user logs in, and then based on the specific user, my website will show different exercises the user has completed in the past, as well as allow the user to add more exercises in the future. My website uses PHP, HTML, and MySQL to search different tables in my database and output the results.
I have tried many different possible solutions, such as sessions in PHP like this, but it did not work. Each PHP page has this at the beginning:
session_start();
and then further down, I have:
$_SESSION["Username"] = $_POST['Username'];
I have also tried hidden input values in HTML, but that did not seem to work quite right either. Each HTML page has this:
<input type="hidden" name="Username" value="Cbartowski">
I have tried a lot of ways to try to have my web page save the username and use that data throughout my pages, but I haven't had any luck. Would sessions in PHP be the way to go? Or hidden input in HTML? Or something else entirely?
Any help would be greatly appreciated!
First of all, using hidden input to store the username is a critical threat to your website.
One can easily check out the username of the person by viewing the source code.
Using PHP sessions is the way to go here.
What i have understood is that you are initializing
$_SESSION["Username"] = $_POST["Username"];
on every page. Now, consider you have two php pages.
One is form-request-handler.php and other is display-user-preferences.php
Now, when user submits the form the username gets set into session variable using the above code snippet on form-request-handler.php page.
Now, when user hits the display-user-preferences.php page, you again set the value of session variable. But since, no post request has been made to this page so Null is get saved into session variable and you are not able to retrieve the required information from the database.
So, whichever php page is handling the post request just initialize your session variable there and use it on other pages.
Sessions variables will be available to you unless you call
session_destroy();
Hope, this helps :)
html hidden input is not a good way because users can see it with the browser show source action.
are u shure session file are saved and the session ID is include in your links ?
if not sessions start a new session each time the user click a link.
have a look in your temp folder each time your clicking a link; if a new session file is created it's because you forget the session ID.
maybe it's the problem.
Check your form method : Should be POST
Check your variable using:
var_dump($_POST['Username']);
So from experience, its better to use post methods when doing user authentication. Purely for security reasons. In addition to this, using PHP's session variables is also the recommended way of passing user information from one page to another.
if you want to store the user name in the session variable, here are some steps you can follow
start the session using session_start();
name the session variable and store the information you want
$_SESSION['what-ever-you-want-to-call-it']=$what-you want to store
eg.$_SESSION['Username']=$_POST['Username']. Note the use of single quotes
You can now call $_SESSION['Username'] anywhere in a php script provide the session has been started before calling it. That is session_start();.
Note break apart the code your working on and ensure each individual piece works. eg,is the post providing you with the username??

Populate form in iframe of external website

I am trying to write a php page that will load several different websites in different iframes. Several of those sites will need the user to login. What I need to do is basically allow the user to only type in the username and password once and then populate all the other forms (that are basically using the same user-pass pair for logging in)
Now i know that since those are external sites you don't have access to the DOM and XSS is not allowed and all, but i was wondering if theres actually any other way to achieve that.
Somebody actually suggested me to simulate keypresses and have a javascript that will basically go from field to field and essentially type in the username and pass but after doing some research I dont think thats possible since you can only simulate the event and not the actual keypress so...any other suggestions?
NOTE: I have also checked this but agreeing with the other sites/domains is not an option in my case!
Thanks -- Mike
that depends.
if those sites share a domain (the parent window and iframes), then it's possible for the top window to communicate with the child iframes. AJAX prevents cross domain (that includes inter subdomains) but iframes can communicate as long as they belong to the same top domain.
see https://stackoverflow.com/a/9338955/575527 and https://stackoverflow.com/a/9676156/575527
a better approach is to have a "top domain cookie" where that cookie is visible in all those iframes (assuming they are of the same top domain). login once using a single login page, then subsequent requests in the pages will need to check the cookie vs the session if that user is logged in.
or if those pages have different domains but access the same database, then one can just then pass the session id as a url parameter to the iframes rather than as cookies. then the website in the iframes will parse the session id and check in the database if those sessions are valid, are current, and are logged in.
all of which need additional CSRF and XSS checking as session IDs are in the open.
You cannot do what you describe in JavaScript.
However, depending on what you need to do with the data/websites once the user is logged in, you may be able to use a remote POST to simulate that behavior. See this question for more info.

PHP sessions and security

I'm trying to decide on the level of security with regards to session management on my php site. at the top of every page is a php tag where I run
if (!isset($_SESSION["user"])) {header('Location: login.php');}
The User session is created on login, do you guys think this is secure enough? The whole site runs in SSL.
Well, being secure has 100's of different topics... But in terms of what you are trying to achieve, yes I think that's fine
I would add some additional validation to checking that $_SESSION['user'] is definately a correct user, and try to compare the session user's IP Address, USER AGENT and other things to detect Session Hi-Jacking
You should also EXIT; after header("Location: X"):
header("Location: xyz.php");
exit;
Yes that will work. To make it less error prone put that snippet in a file and include it at the top of each page. That way you just edit one place to make changes to the logic.
Also, your Location header is supposed to contain the entire URL starting with https: according to the RFC specifications. It may still work for some browsers but should not be depended on.
I think it's better to create a random token string when your user wants to login to your website. Then check it in every page beside your previous code. I used $_SERVER['REMOTE_ADDR'] , $_SERVER['HTTP_USER_AGENT'] and a random string to make it.
Well, at least once per load you will need also validate the user, otherwise you are just checking if the session exists.

PHP security question

If I want people only accessing a certain page on my webpage by using a link within my website, and not typing it in the address box then would this do...
Please note that the user would first have to login to their account and all member pages have been set so that the user must login into their account before accessing member pages.
if (isset($_SERVER['HTTP_REFERER'])) {
// show page content
}
else {
header('Location:http://');
exit();
}
Am I correct in saying, that if a link is clicked then the page will show, but if the link is not clicked and the address of where the link points to is typed in the address bar it will do a redirect.
I am asking as the link will direct people to a form, and I don't want that form being accessed without first having some variables set on the previous page, or being accessed without logging in (as people could create their own link on another website which points to the same location)
Thanks
It is not secure in any way. From here:
The address of the page (if any) which referred the user agent to the
current page. 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.
Users can set the referrer to whatever they want, so no, checking that that's set is not a secure way of checking that they came to your second page via the first.
HTTP_REFERRER can be spoofed pretty easily. When you want forms to be secure, implement some sort of CSRF protection by adding a hidden token to the field and ensuring it matches when you submit the form. Your best bet is to make sure their credentials are actually valid.
This seems very buggy to me; if you want certain variables to be set and / or a user to be logged in, just check for all these conditions at the top of the form-page and redirect the visitor somewhere else if the conditions are not met.
I'm unsure what you mean about having variables set from the previous page, or how you are achieving this. Its possible of course, but I would be interested how you are going about it.
You are correct in your question however, that when coming from another page the referrer will be set to that page. In terms of security however, its not a good idea to rely on it as it is easily spoofed. The only sure way is to ask for credentials (a username and password etc) which it sounds like you are already doing.
Could you not test to see if the variables are set, and if they aren't then redirect?

Categories