-
Posts
2,134 -
Joined
-
Last visited
-
Days Won
42
Everything posted by benanamen
-
If you your datetime is coming from Mysql you can let the DB do the work. SELECT DATEDIFF(NOW(),'2016-07-02 16:41:48') AS date_time <?= "<span class='timeAgo'>{ago($row['date_time'])}</span>" ?>
-
I need your help applying a script to more databases
benanamen replied to EricOnAdventure's topic in PHP Coding Help
Eric, I have done a quick review of the code in that script. Get your money back and don't use it. There are several serious security issues with it. One of the more glaring ones is that it uses MD5 or SHA256 for password encryption. It will also output the exact server error messages directly to the user providing valuable information to a hacker. -
Funny you should say that. I already do that. It is part if the login script that I have not posted. I log all login attempt statuses, good or bad, what the bad user and pass was and IP and datetime. As I think about it, it wouldnt take much modification to track just the reset data. Table is already there, just need to remove the hash and expiration columns and put them in the users table.
-
I don't care how @Jaques1 responds (It took a few posts ). His knowledge of Security is NSA, CIA, & MI6 level expertise. Where ever he learned it, it wasn't from the Php Manual.
-
Since @muddy_funster brought up a specific case that I was going to post about, I will post here. Especially interested in @Jaques1 feedback. In the case where you want to track the reset data you obviously would need a separate password reset table. My question is, what would be the best/most secure way to handle it. Currently my forgot password reset code will add a row with the proper data needed for a reset along with an expiration datetime. On successful reset only the hash is deleted leaving only tracking data. Any hashes not reset are not usable after the timeout. The following code was originally written several years ago with only the hashing and password generation parts updated per the recommended code from @Jaques1. Anyone see any problems or recommend any changes? forgot.php <?php /* * Last Modified <!--%TimeStamp%-->6/23/2016 10:39 AM<!----> */ require('./config.php'); $show_error = false; if (!empty($_POST)) { //------------------------------------------------------------------------ // Trim $_POST Array //------------------------------------------------------------------------ $_POST = trim_array($_POST); //------------------------------------------------------------------------ // Validate Form Input //------------------------------------------------------------------------ $error = array(); if (empty($_POST['forgot'])) { $error['forgot'] = 'Email Required.'; } //------------------------------------------------------------------------ // Check for errors //------------------------------------------------------------------------ if (count($error)) { $show_error = true; } else { // Check DB for matching username and password. $sql = "SELECT user_id, email FROM users WHERE email = ?"; $stmt = $pdo->prepare($sql); $stmt->execute(array( $_POST['forgot'] )); $row = $stmt->fetch(); //--------------------------------------------------------------------------------------------- // No Results - Redirect //--------------------------------------------------------------------------------------------- if (!$stmt->rowCount()) { die(header("Location: {$_SERVER['SCRIPT_NAME']}?fail")); } //--------------------------------------------------------------------------------------------- // Check Reset table to see if there are multiple incomplete reset attempts // Block access if too many. //--------------------------------------------------------------------------------------------- $user_id = $row['user_id']; /* $sql = "SELECT COUNT(*) from password_reset WHERE user_id = ? AND password_reset_key <>'' " ; $stmt = $pdo->prepare($sql); $stmt->execute(array( $user_id )); $count = $stmt->fetchColumn(); if ($count==3){ echo '<div class="error_custom">Too Many Incomplete Password Resets. Contact Site Admin</div>'; //echo $count; exit; } */ //--------------------------------------------------------------------------------------------- // Log Password Reset Data //--------------------------------------------------------------------------------------------- // From http://forums.phpfreaks.com/topic/298729-forgotten-password/?hl=%2Bmcrypt_create_iv#entry1524084 // generate 16 random bytes $raw_token = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM); // encode the random bytes and send the result to the user $encoded_token = bin2hex($raw_token); // hash the random bytes and store this hash in the database $token_hash = hash('sha256', $raw_token); /** * Interval specification. * * The format starts with the letter P, for "period." Each duration period is * represented by an integer value followed by a period designator. If the * duration contains time elements, that portion of the specification is * preceded by the letter T. * * @link http://www.php.net/manual/en/dateinterval.construct.php * * String to time option * $password_reset_expiration_datetime = date('Y-m-d H:i:s', strtotime("+5 min")); * */ $period_designator = 'PT'; $timespan = 'M'; //Minutes //$period_designator = 'P'; $timespan ='D'; //Days $timespan_add = 1; // Amount of days or minutes $time = new DateTime(date('Y-m-d H:i:s')); $time->add(new DateInterval($period_designator . $timespan_add . $timespan)); $password_reset_expiration_datetime = $time->format('Y-m-d H:i:s'); $sql = "INSERT INTO password_reset (user_id, password_reset_username_email, password_reset_requesters_ip, password_reset_key,password_reset_expiration_datetime) values(?, ?, ?, ?, ?)"; $stmt = $pdo->prepare($sql); $stmt->execute(array( $user_id, $_POST['forgot'], $_SERVER["REMOTE_ADDR"], $token_hash , $password_reset_expiration_datetime )); //--------------------------------------------------------------------------------------------- // Email Reset Data //--------------------------------------------------------------------------------------------- $mail_to = $row['email']; $mail_from_name = "Meet Market"; $mail_subject = "Lost Password"; $mail_message = "You have requested a forgotten password reset." . PHP_EOL . PHP_EOL; $mail_message .= "Click the link below or enter the following code on the Password Reset page. Reset Code: $encoded_token\n$url_website/reset.php?k=$encoded_token"; // Send mail mail($mail_to, $mail_subject, $mail_message, "From: $mail_from_name <$email_from>\r\n"); die(header("Location: reset.php?sent")); if (DEBUG == 1) { debug_show_sql(); } } // End if } // End (!empty($_POST)) include('./includes/header.php'); ?> <div class="container"> <?php if (isset($_GET['fail'])) { echo '<div class="error_custom">Invalid Username or Email</div>'; } //-------------------------------------------------------------------- // Display Logo //-------------------------------------------------------------------- logo(); //--------------------------------------------------------------------------------------------- // Forgot Password Form //--------------------------------------------------------------------------------------------- if ($show_error) { show_form_errors($error); } ?> <form class="form-horizontal" action="<?= $_SERVER['SCRIPT_NAME'] ?>" method="post"> <div class="form-group <?= !empty($error['forgot']) ? 'has-error' : '' ?>"> <label class="col-md-4 control-label" for="forgot">Enter Email</label> <div class="col-md-4"> <input id="forgot" name="forgot" type="text" placeholder="Email Address" class="form-control input-md"> <span class="help-block">A password reset email will be sent to you.</span> </div> </div> <div class="form-group"> <div class="col-md-offset-4 col-sm-10"> <button id="submit" type="submit" name="submit" class="btn btn-primary">Reset Password</button> <a href="./login.php">Login</a> </div> </div> </form> </div><!--/ container --> <?php include('./includes/footer.php'); ?> reset.php <?php /* * Last Modified <!--%TimeStamp%-->3/11/2016 9:20 PM<!----> */ session_start(); require('./config.php'); if ($_POST) { //------------------------------------------------------------------------ // Trim $_POST Array //------------------------------------------------------------------------ $_POST = trim_array($_POST); //------------------------------------------------------------------------ // Validate Form Input //------------------------------------------------------------------------ if (empty($_POST['reset_code'])) { $error['reset_code'] = 'Reset Code required.'; } if (empty($_POST['new_password'])) { $error['new_password'] = 'New Password is required.'; } if (empty($_POST['new_password_confirm'])) { $error['new_password_confirm'] = ' Confirm New Password is required.'; } elseif ($_POST['new_password'] != $_POST['new_password_confirm']) { $error['new_password_confirm'] = 'Passwords do not match.'; } //--------------------------------------------------------------------------------------------- // Check for errors //--------------------------------------------------------------------------------------------- if (count($error)) { $show_error = true; } else { // From http://forums.phpfreaks.com/topic/298729-forgotten-password/?hl=%2Bmcrypt_create_iv#entry1524084 $encoded_token = $_POST['reset_code']; // decode the token and hash it $raw_token = hex2bin($encoded_token); $token_hash = hash('sha256', $raw_token); // Check DB for matching reset key. $sql = "SELECT user_id, password_reset_username_email, password_reset_key FROM password_reset WHERE password_reset_key=?"; $stmt = $pdo->prepare($sql); $stmt->execute(array( $token_hash )); $row = $stmt->fetch(PDO::FETCH_ASSOC); //--------------------------------------------------------------------------------------------- // No Results - Redirect //--------------------------------------------------------------------------------------------- if (!$stmt->rowCount()) { die(header("Location: {$_SERVER['SCRIPT_NAME']}?fail")); } //--------------------------------------------------------------------------------------------- // Update Password //--------------------------------------------------------------------------------------------- $hashed_new_password = password_hash($_POST['new_password'], PASSWORD_DEFAULT); $sql = "UPDATE users SET password= ? WHERE user_id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute(array( $hashed_new_password, $row['user_id'] )); /** * Delete used reset key. We are leaving unused keys to be able to see how * many times a user requests a reset before they complete a password reset. * Since reset keys are only valid for limited time there is no risk leaving * the unused keys. * * TODO: DEV: Might be a good idea to block password resets after X times of not * completing a password reset. i.e. User has submitted 3 password reset requests * and hasnt entered reset key and new password. They are now blocked. Alert admin. * * $sql = "SELECT COUNT(*) from password_reset WHERE user_id = ? AND password_reset_key <>'' " ; * **/ $sql = "UPDATE password_reset SET password_reset_key = ? WHERE user_id = ? AND password_reset_key = ?"; $stmt = $pdo->prepare($sql); $stmt->execute(array( NULL, $row['user_id'], $row['password_reset_key'] )); if (DEBUG == 1) { debug_show_sql(); } //--------------------------------------------------------------------------------------------- // Send Reset Email //--------------------------------------------------------------------------------------------- $mail_to = $row['password_reset_username_email']; $mail_from_name = "Some Site"; $mail_subject = "Password has been reset"; $mail_message = "Password has been reset"; // Send mail mail($mail_to, $mail_subject, $mail_message, "From: $mail_from_name <$email_to>\r\n"); die(header("Location: login.php?reset")); } // End if ($validated) } // End (!empty($_POST)) //--------------------------------------------------------------------------------------------- // Reset Code Form //--------------------------------------------------------------------------------------------- include('./includes/header.php'); if (isset($_GET['fail'])) { echo '<div class="error_custom">Invalid code or time expired</div>'; } logo(); // Display Logo if (isset($_GET['sent'])) { echo '<div class="success">A reset code has been been emailed to you. Enter code below to reset your password or click link in email.</div>'; } isset($show_error) ? show_form_errors($error) : ''; // Display Form errors if any if (isset($_GET['k'])) { $reset_code = $_GET['k']; } if (isset($_POST['reset_code'])) { $reset_code = $_POST['reset_code']; } ?> <form class="form-horizontal" action="<?= $_SERVER['SCRIPT_NAME'] ?>" method="post"> <div class="form-group <?= !empty($error['reset_code']) ? 'has-error' : '' ?>"> <label class="col-md-4 control-label" for="reset_code">Reset Code</label> <div class="col-md-5"> <input id="reset_code" name="reset_code" type="text" placeholder="Reset Code" class="form-control input-md" value="<?= !empty($reset_code) ? htmlspecialchars($reset_code) : '' ?>"> </div> </div> <div class="form-group <?= !empty($error['new_password']) ? 'has-error' : '' ?>"> <label class="col-md-4 control-label" for="new_password">Enter New Password</label> <div class="col-md-5"> <input id="new_password" name="new_password" type="text" placeholder="Enter New Password" class="form-control input-md" value="<?= !empty($_POST['new_password']) ? htmlspecialchars($_POST['new_password']) : '' ?>"> </div> </div> <div class="form-group <?= !empty($error['new_password_confirm']) ? 'has-error' : '' ?>"> <label class="col-md-4 control-label" for="new_password_confirm">Confirm New Password</label> <div class="col-md-5"> <input id="new_password_confirm" name="new_password_confirm" type="text" placeholder="Confirm New Password" class="form-control input-md" value="<?= !empty($_POST['new_password_confirm']) ? htmlspecialchars($_POST['new_password_confirm']) : '' ?>"> </div> </div> <div class="form-group"> <div class="col-md-offset-4 col-sm-10"> <button id="submit" type="submit" name="submit" class="btn btn-primary">Reset Password</button> <a href="./login.php">Login</a> </div> </div> </form> <?php include('./includes/footer.php'); ?>
-
Why does this forum automatically insert double breaks before the first text line of a quote? If you edit the post and remove the breaks, they stay ok.
-
Don't be. That's not even how I did it. * @Jaques1 is just being @Jaques1 and he is right to be serious about security related issues. Even a computer that is not plugged in the wall and not connected to the net needs to be secured.
-
@muddy_funster, I have gained complete access to a server through an SQL injection exploit. It is really not difficult if you know what you're doing. Security should always be taken seriously.
-
I need your help applying a script to more databases
benanamen replied to EricOnAdventure's topic in PHP Coding Help
I logged into their demo and see this at the top of the page: Deprecated: Function ereg_replace() is deprecated in /home/quadodo/public_html/includes/SQL.class.php on line 60 That is enough information to know this code is old and should not be used. OP, ditch this code. It is no good. -
Start here: https://phpdelusions.net/pdo
-
In my "defense" my response was directed to the "Experts" that posted on this thread and not to the OP. An expert doesn't need an explanation of obsolete code. Anyone with enough expertise to respond with help to the OP "should" know enough to spot the obsolete code and at least point it out even if you are going to help fix it. To my surprise, nobody did. Had I responded to the OP, I would have directed OP to the PDO tutorial that I just did. In the words of Forrest Gump, "That's all I have to say about that".
-
Troll? Hardly! No one in this thread even mentioned a single thing about the OP's obsolete code. So I am a troll because I pointed out something VERY important, not only for the OP, but for the web? How are you helping when you don't even tell the OP that his code is obsolete and point him the way of PDO or at least Mysqli? Help with bad code all you want but at least tell the OP so he knows. In due time? For real? The OP is here right now. Teach him the right way while he is here, not some mystical time in the future. OP: Check out this link on how to use PDO: https://phpdelusions.net/pdo
-
Benanamen say: Stop teaching people how to use code that has been deprecated starting over TEN years ago. There is just no excuse to keep that kind of code alive. Better to teach the OP's PDO or at the least Mysqli. There is no reward waiting for you in programmers heaven for fixing obsolete code. Word on the street is you may even get sent somewhere else for doing it.
-
Since I don't know what it is you're actually trying to accomplish I can't give you a good answer. You have provided no code. Thats pretty much the first thing you need to provide if you have it. How about an explanation of what you're trying to accomplish, the big picture. (Not how to do what you think needs to be done.) The ol what have you tried, what was the result, what is the expected result, along with a good overview of what is to be accomplished... I am sure you know of this.
-
Experience shows that once they get their old code working they never convert it later. Not always, but mostly. The only thing that is truly going to solve this is when every server has PHP 7.
-
Twitter style @ allerts
benanamen replied to Muddy_Funster's topic in PHPFreaks.com Website Feedback
Lol! Yeah, I know. It is the natural reaction when you hear that somebody is talking about you. "What did they say, what did they say, tell me tell me." -
The user should not dictate how you store the data. Allow the user whatever format you decide for him to enter it but piece it back together to store it as a proper date time field. You can parse that out anyway you want later.
-
Click the info button on your remote control and it will give you the start and end time of your show. You could also look in the TV Guide if you have one. Some systems can give you all the start and end times for that particular show during the programming period. * split posted for some reason
-
Twitter style @ allerts
benanamen replied to Muddy_Funster's topic in PHPFreaks.com Website Feedback
I am on another Forum that does exactly that. It hasn't seemed to provide any real benefit to me except to know somebody was talking about me. -
Any duration needs a start and end. Simply have a start and end datetime columns in your database, unless one of them is calculated off one of the dateimes, then you just need one date time column that is either a start or end date time.
-
Why are you people helping get obsolete insecure code working? You should be helping him convert this to PDO.
-
What exactly is the code you tested in IE8?
-
I have done pretty exhaustive testing. I wasn't going to say something is the correct way to do it just because @Jaques1 said so or anyone else for that matter. I want to know, by code if something is wrong or not. Although I preach the request method on forums, I still use if ($_POST) in apps that I am the sole coder and are not public access. Your right. The IE8 issue is specific to how it handles submit and will completely fail with notice of any kind that it did. Either of those will work. Checking for submit will not. On this issue, it doesn't matter one bit if all the data is correct. IE8 behaves exactly the same as if you didn't click the submit button. The script cannot "Do it's job" if it never runs.