scootstah
Staff Alumni-
Posts
3,858 -
Joined
-
Last visited
-
Days Won
29
Everything posted by scootstah
-
That's great until your database gets hacked and they have free passwords. Just because 1 or 2 people have access doesn't mean you can't be hacked. If Sony and Steam can be, you can be. Yes, the attacker would need to have the password hashes so they must have obtained them from the database in some way. Either finding an SQL injection vulnerability, through a CMS somehow, or by gaining access to the database directly. Well no, but it slows them down at least. Nothing too crazy. A 10 character long unique random string will work fine. My approach uses a stronger hashing algorithm (sha512 vs sha256) as well as the more secure hash_hmac() (vs hash(), which I already explained the difference between the two). Also, DarkFreak needlessly re-hashes the hash a lot of times, which really does nothing. It depends what sort of brute force you are talking about. Do you mean brute force the login from the website, IE: try a bunch of username/password combination until one works? Yeah that can be slowed down by having login attempt restrictions. Note though that use of proxies, cookie clearing, different usernames etc can all bypass such attempts. It is difficult to secure that really well without inconveniencing honest users. If however you mean brute forcing the hashes by means of finding collisions and such, there's nothing you can do to "prevent" that, but you can make it more difficult. They would of course need to have the hashes available so they would have had to already obtain them from the database in some way. Once they do that it's just a matter of time and how much effort they put forth to cracking them. If you use my hash_hmac() approach (which uses the cryptographic key to compute the hash) then they will also need that key in order to brute force the hash. It's true, there's a lot of controversy on the subject. The thing you need to ask yourself is how likely you are to being hacked. If you have a small community website or some small e-store or something like that, chances are you are a very small target. And as such, anyone that does attempt something is probably unlikely to succeed due to lack of motivation and/or resources. Keep in mind that no matter what sort of hashing algorithm you use, unless they gain access to your database you're fine. You could store them as plain text as you want and so long as they never get your database, they can never crack the passwords (except by trying to login until they get it right - which has no bearing on whether or not the password is hashed or salted or whatnot). So put simply, pick something that isn't needlessly complicated (such as my approach) and go with it. Anything more than MD5/SHA1 with properly salted hashes will take a significant amount of time for your average script kiddie to crack. And that's IF they even get them from the database in the first place. It sounds like you are way too concerned about this. Well like I said, there's a lot of controversy on the subject. There's a million different ways. No offense meant to DarkFreaks, but his approach seems inefficient and unnecessarily complicated. Rehashing 100,000 times is going to exactly nothing in terms of more secure. In fact it may even do the opposite. You can either search for days and weeks until you find something you feel comfortable with, but I think you are just wasting your time. Pick something reasonable and go with it.
-
Because hash_hmac() also requires a cryptographic key to compute the hash, and hash() does not. Even if they have a full dump of your database with the hashes, trying to brute force them would be futile without the cryptographic key.
-
For the '===' and '!==', see my reply here: http://www.phpfreaks.com/forums/index.php?topic=352807.msg1666061#msg1666061 The spacing is just to make the code easier to read.
-
Is your client the only one with the problem? Has he tried a different browser?
-
Lenovo has always made high quality laptops. So I would imagine they are.
-
Some ideas on making odd & even rows to color in with CSS
scootstah replied to Shadowing's topic in PHP Coding Help
3 equal signs is a comparison operator that also checks type. For example... $str = '17'; if ($str == 17) { // true } if ($str === 17) { // false } The first if() returns true, because there is no type checking. '17' and 17 evaluate to the same. The second if() returns false because they are not the same type. '17' is a string and 17 is an integer. This operator is most commonly used for booleans. The reason is that in PHP as long as a variable holds a value (must be at least a positive number and not zero) it will evaluate to true, even if it's not a boolean. $str = '17'; if ($str == true) { // true } So this if() will return true, because $str holds a value. If you wanted to actually see if $str holds the boolean "true", you'd need 3 equal signs. $str = '17'; if ($str === true) { // false } Hope that helps. -
Some ideas on making odd & even rows to color in with CSS
scootstah replied to Shadowing's topic in PHP Coding Help
Or use CSS. tr:nth-child(odd) { background: #fff; } tr:nth-child(even) { background: #000; } -
This should get you started... users table CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(30) NOT NULL, `password` char(128) NOT NULL, `salt` char(10) NOT NULL, PRIMARY KEY (`id`) ) the hashing function function hash_password($password, $salt = null) { if (!is_null($salt)) $salt = substr(sha1(uniqid(mt_rand(), true)), 0, 10); // this should be a long, random string // stored somewhere safe $key = 'abcdef'; $hash = hash_hmac('sha512', $password, $key); return array($hash, $salt); } register.php if (!empty($_POST)) { $username = $_POST['username']; $password = $_POST['password']; if (!empty($username) && !empty($password)) { list($hash, $salt) = hash_password($password); // INSERT INTO users VALUES (0, $username, $hash, $salt); } } login.php if (!empty($_POST)) { $username = $_POST['username']; $password = $_POST['password']; if (!empty($username) && !empty($password)) { // SELECT username, password, salt // FROM users // WHERE username = $username // $row = fetch row list($hash) = hash_password($password, $row['salt']); if ($hash == $row['password']) { // hashes match, log in } } } Yeah, I remember reading a big article about why it was bad. But in my 47 seconds of Googleing for it, couldn't find it. Oh well.
-
This is presentation: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Registration Page</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="style.css" type="text/css" charset="utf-8"> <link rel="stylesheet" href="styles.css" type="text/css" charset="utf-8"> //Some Javascript... </script> </head> <body> //Some Styling... <!-- content goes here --> <h1>Register</h1> This is business: ob_start(); error_reporting(0); $_POST = array_map('secure', $_POST); if($_POST['submit']) { $user_name = mysql_real_escape_string($_POST['user_name']); $query = mysql_query("SELECT * FROM xxxxusers WHERE user_name='$user_name'"); $query = mysql_query("SELECT * FROM xxxusers WHERE user_name='$user_name'"); if(mysql_num_rows($query) != 0) { echo "<div style="font-size: 9pt; font-weight: bold;color: red;">Username already exists</div>"; } else { $user_password = mysql_real_escape_string($_POST['user_password']); $user_pass = mysql_real_escape_string($_POST['user_pass']); $user_email = $_POST['user_email']; $query = mysql_query("SELECT * FROM xxxxusers WHERE user_email='$user_email'"); $query = mysql_query("SELECT * FROM xxxusers WHERE user_email='$user_email'"); if(mysql_num_rows($query) != 0) { echo "<div style="font-size: 9pt; font-weight: bold;color: red;">Email already exists</div>"; } else { $enc_password = md5($user_password); $enc_password = md5($user_pass); if($user_name && $user_password && $user_pass && $user_email) { if (strlen($user_name)>20) { echo "<div style="font-size: 9pt; font-weight: bold;color: red;">Your Name is Too Long</div>"; } $email = htmlspecialchars($_POST['user_email']); if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) { echo "<div style="font-size: 9pt; font-weight: bold;color: red;">E-mail address not valid</div>"; } { require "dbc.php"; mysql_query("INSERT INTO xxxxusers stuff....) VALUES(stuff....) ") or die(mysql_error()); mysql_query("INSERT INTO xxxusers stuff....) VALUES(stuff....) ") or die(mysql_error()); } } else echo "<div style="font-size: 9pt; font-weight: bold;color: red;">All Fields Are Required</div>"; } } } ob_end_flush(); They shouldn't be intertwined together. It makes things hard to follow and maintain. Ideally, they shouldn't even be in the same file. Or directory. Keep all the business in one place, keep all the presentation in another place. Use a function to call upon presentation files when you need them. Presentation files (or templates if you prefer) should only contain HTML and light PHP usage if needed. Things like variables, flow control (if/else) and loops (foreach, while) are all considered okay (as long as it's fairly light). Take a look at the MVC pattern to get a better idea what I am talking about. I'm not saying you have to fully implement the MVC pattern, but simply separating business from presentation will go a long way in making your code more efficient and easier to read and maintain.
-
True. Thanks for pointing that out.
-
This is why you want to separate business from presentation. You would need to completely re-write that with that in mind. But if you want a band-aid, move your ob_start() to the very top of the page and ob_end_flush() to the very bottom. Then your header() should work.
-
PHP: No, unless you explicitly tell Apache to parse image files as PHP. JS: Possibly, in older browsers.
-
For the record, this is called the singleton pattern. It works like this class Singleton { public static $instance; private function __construct() { } public static function getInstance() { if (!self::$instance) self::$instance = new Singleton; return self::$instance; } } $singleton = Singleton::getInstance(); Basically, you make the constructor static which prevents it from being instantiated outside of the class. Then, by calling the getInstance method, you instantiate the class internally and then return it. Since the $instance variable is static, this can only happen once. If you call the getInstance method again it simply returns the instance instead of instantiating it multiple times.
-
PHP doesn't really care what browser accesses it. It isn't run by a browser so it behaves the same on every browser. So post the code so we can see what is going on.
-
The location would be... $obj->results[0]->geometry->location Which would contain stdClass Object ( [lat] => 38.8987149 [lng] => -77.0376555 ) Also, here's a formatted version of that mess you posted. Maybe it will help you see the flow of logic easier. stdClass Object ( [results] => Array ( [0] => stdClass Object ( [address_components] => Array ( [0] => stdClass Object ( [long_name] => 1600 [short_name] => 1600 [types] => Array ( [0] => street_number ) ) [1] => stdClass Object ( [long_name] => Pennsylvania Ave NW [short_name] => Pennsylvania Ave NW [types] => Array ( [0] => route ) ) [2] => stdClass Object ( [long_name] => Northwest Washington [short_name] => Northwest Washington [types] => Array ( [0] => neighborhood [1] => political ) ) [3] => stdClass Object ( [long_name] => Washington [short_name] => Washington [types] => Array ( [0] => locality [1] => political ) ) [4] => stdClass Object ( [long_name] => District of Columbia [short_name] => DC [types] => Array ( [0] => administrative_area_level_1 [1] => political ) ) [5] => stdClass Object ( [long_name] => United States [short_name] => US [types] => Array ( [0] => country [1] => political ) ) [6] => stdClass Object ( [long_name] => 20500 [short_name] => 20500 [types] => Array ( [0] => postal_code ) ) ) [formatted_address] => 1600 Pennsylvania Ave NW, Washington, DC 20500, USA [geometry] => stdClass Object ( [location] => stdClass Object ( [lat] => 38.8987149 [lng] => -77.0376555 ) [location_type] => ROOFTOP [viewport] => stdClass Object ( [northeast] => stdClass Object ( [lat] => 38.900063880291 [lng] => -77.036306519708 ) [southwest] => stdClass Object ( [lat] => 38.897365919709 [lng] => -77.039004480291 ) ) ) [partial_match] => 1 [types] => Array ( [0] => street_address ) ) ) [status] => OK )
-
substr() echo substr('Welcome to my store. Would you like to buy something? We have really good noodles and fishes in doodle pools.', 0, 30) . '...';
-
Of course you'll need the salt, that's the whole point. You need to store the salt in the users table and retrieve it when they try to log in. There's a plethora of tutorials out there that demonstrate this. In fact I think there was a few other topics on the matter not too long ago on these forums. Also, keep in mind that hashing a hash 100,000 times isn't doing any good at all except waste server resources.
-
Salts mean that multiple users with the same password will have different hashes, therefore making rainbow tables useless (you would have to create a rainbow table for each user). I don't think that is correct. If you and I both had "santa_claus" for our passwords, wouldn't the same Hash generate DIFFERENT hashed values 99.999% of the time regardless of whether a Salt was used? No. If you MD5 "santa_claus" it's always going to be the same hash, unless a salt is used. Without using a salt all you need is a rainbow table and you can easily reveal passwords based on their hash. If multiple people have the password "santa_claus", then multiple people will have identical hashes. This cuts down on the amount of work required to uncover passwords, because they can reveal multiple passwords with a single hash. Using salts means that rainbow tables are only effective if you create one for each individual user with their unique salts. Obviously, this would require considerable time and resources... rainbow tables are quite large. And so you recommend WHAT instead?? Debbie A longer, slower hashing algorithm. Like SHA512 or bcrypt. What do you mean by "slower hashing algorithm"?? Debbie MD5 and SHA1 are not secure password storing hashes because they are fast. A modern computer can generate MD5 or SHA1 hashes very, very fast. Which means that finding collisions takes hours and not years. A slower algorithm (like sha512 or bcrypt) takes considerably more time to compute and is therefore more secure. Creating rainbow tables or finding collisions would take a very long time compared to md5 or sha1. Coupling this with hash_hmac should be good enough for most applications. hash_hmac makes use of a cryptographic key when making hashes. What this means is that in order to use rainbow tables or brute force hashes the attacker would also need the cryptographic key residing in the file system. So not only does the attacker need to compromise the database, but the file system as well.
-
Not with PHP. You would need Javascript for that.
-
Salts mean that multiple users with the same password will have different hashes, therefore making rainbow tables useless (you would have to create a rainbow table for each user). And so you recommend WHAT instead?? Debbie A longer, slower hashing algorithm. Like SHA512 or bcrypt. I use Prepared Statements, so I don't believe that I need to worry about that. Debbie You don't.
-
md5() and sha1() are garbage for storing passwords.
-
You can, the same way that you can with POST. The query string would look like example.com?favorite[]=1&favorite[]=2&favorite[]=3
-
why do people still concatenate variables in queries wrapped in double quotes? I'm still trying to figure this out. It's not needed, more work and can lead to more error(s). Because there are times when you still need to concatenate things even when using double quotes. Or at the very least use {}. It is just habit and personal preference. I don't see how it could lead to more errors. It can lead to more errors if the coder does not know how to properly concatenate. Haha, well that could be said about anything. "It could lead to errors if the coder doesn't know how to use a semi-colon".
-
why do people still concatenate variables in queries wrapped in double quotes? I'm still trying to figure this out. It's not needed, more work and can lead to more error(s). Because there are times when you still need to concatenate things even when using double quotes. Or at the very least use {}. It is just habit and personal preference. I don't see how it could lead to more errors.