-
Posts
4,207 -
Joined
-
Last visited
-
Days Won
209
Everything posted by Jacques1
-
Security concerns while displaying output to a browser
Jacques1 replied to ajoo's topic in PHP Coding Help
You must specifiy the character encoding when you escape data. Without this, you're flying blind. If you're lucky, the browser will pick the same encoding which htmlspecialchars() happens to use by default, but this definitely isn't something you should rely on. For example, Internet Explorer is infamous for “guessing” the encoding if there's no explicit declaration. An attacker can use this to bypass escaping entirely: They give you a string which is harmless when interpreted with your default encoding, so htmlspecialchars() takes no action. But when Internet Explorer does its guessing and chooses a different encoding, the harmless string suddenly turns into malicious HTML. Try this in any version of Internet Explorer: <?php // Mimic the guessing behaviour of IE 7 and earlier. header('Content-Type: text/html;charset=utf-7'); $input = "+ADw-script+AD4-alert('XSS!')+ADw-/script+AD4-"; /* * Since you forgot to tell htmlspecialchars() which character encoding it should use, it will * assume ISO 8859-1 or UTF-8 depending on the PHP version. When $input is interpreted with those * encodings, it's meaningless and will not be touched by htmlspecialchars(). Unfortunately, the * client uses UTF-7! And in that case, the input means this: <script>alert('XSS!')</script> */ $maybe_safe = htmlspecialchars($input); // There's our XSS vulnerability, regardless of the fact that we've used htmlspecialchars(). echo $maybe_safe; So escaping without an encoding declaration is futile. You first need to define the character encoding of your HTML document if you haven't done that already: // If you're not using UTF-8, change this accordingly. header('Content-Type: text/html;charset=utf-8'); And then you need to use this exact encoding for htmlspecialchars(). It's probably best to write a custom wrapper function: function html_escape($input, $encoding) { /* * Note the flags: * * ENT_QUOTES tells the function to escape both single and double quotes. * Otherwise, single quotes will be ignored and can be used for attacks. * * ENT_SUBSTITUTE tells the function to replace invalid Unicode sequences * with an error symbol. Otherwise, the entire input will be replaced with * an empty string, which is probably not what you want. */ return htmlspecialchars($input, $encoding, ENT_QUOTES | ENT_SUBSTITUTE); }- 5 replies
-
- ajoo
- output to a browser
-
(and 2 more)
Tagged with:
-
You can, but you need to understand what this expression actually means. This has nothing to do with nested methods. The inner method simply returns an object, and then you call a method of that returned object: <?php // the short form: $base_object->some_method()->some_other_method(); // what this actually does: $returned_object = $base_object->some_method(); $returned_object->some_other_method(); Of course you can continue the chaining if the outer method again returns an object etc.
-
Hi, this class has already been written for you: PDO. Note that the old mysql_* functions are long obsolete and will be removed in one of the next PHP releases. Didn't you see the big red warnings in the PHP manual? When you switch to PHP 5.5, you'll also get tons of deprecation warnings for your script. So using this dying extension as the basis for your new database class really isn't a good idea.
-
Let me Google that for you again: “0x31303235343830303536” No explanations? The first page starts with three Stack Overflow threads explaining exactly what this is and even which tool it comes from. What more do you need?
-
Importing CSV into MYSQL through php not working right
Jacques1 replied to Raz3rt's topic in PHP Coding Help
This looks like an issue with the CSV content and/or problems with the character encoding. Check the CSV with a hex editor to see what it actually contains; there may be invisible characters. Also make sure that the encodings are correct. Is the CSV file indeed stored as UTF-8? Is character_set_database also UTF-8? If not, use the CHARACTER SET clause. -
To be exact, it yields true if the variable doesn't exist, or if it has a falsy value. So empty($var) is the same as !isset($var) || !$var In your code above, you know for sure that the variable exists, so you can jump straight to !$var. There's simply no need for empty(). I'm not saying that it's wrong, but it's overly complicated and makes no sense from a technical perspective. Also be aware that the string "0" is considered falsy as well. This can lead to unintended behaviour, but it should be OK in your case.
-
When you're not sure about the content of a variable, check it. This will tell you exactly what it does and does not contain: var_dump($row); You'll see that there is no key named “s.stream_status”. It's stream_status, because that's the name of the column. The “s” is just an internal qualifier which tells MySQL which table it should get the column from (because multiple tables may have the same columns).
-
You've called your variable $mail, but you're checking for $email. Besides that, this is all a bit weird. What's the point of the empty() checks? The variables obviously do exist, because you've defined them right above this part. So why not just check for !$your_variable? Or rather: Why not leave out all the superfluous variables and use the $_POST array directly? This makes your code much shorter and will also prevent warnings if the POST parameters do not exist at all. There are also issues with your HTML. You're missing the closing tag of the form, and you cannot have multiple checkboxes with the same name (well, this is actually a PHP issue). If you want an array of values, you need the bracket syntax: rate[].
-
Hi, whatever $this->_db contains, it's not an object. Are you sure you've initialized the attribute?
-
rand(), mt_rand() and uniqid() produce very poor pseudo-random numbers derived from trivial factors like the server time and the process ID. With a bit of effort, it's in fact possible to predict the next value. If the IDs aren't secret, and if the traffic of your website is low, then those functions may still be good enough in your case. But if you want “real” random numbers, you must use the generator of your operating system. There are three ways to access it: through openssl_random_pseudo_bytes() as mentioned by mac_gyver through mcrypt_create_iv() by reading directly from the system device (e. g. /dev/urandom) If you read 16 bytes from any of those interfaces, you don't have to worry about collisions. There won't be any.
-
Please make sure you understand the other position before you start arguing against it. Two guys angrily yelling at a straw man looks rather silly. Let's take a deep breath and turn this little bashing into an actual discussion. So you absolutely hate the type system of PHP and can't deal with it? Cool. Pick another language. If you want to explicitly declare the types of variables, you may like Java. If you also want to prevent implicit conversions, you'll have to look into languages like Ada or Eiffel. Both have very strict type systems and will not let you do anything unexpected. Personally, I'm not a big fan of PHP either, which is why I use Ruby most of the time. You're preaching to the choir. But if you choose a language with an extremely weak type system and then start whining about weak typing, then that's, well, not very intelligent. It's like choosing Java only to complain about OOP. Working against a language and trying to turn it into something different is a bad idea. You can clutter your PHP code with tons of manual type checks, but even then it will still be a weakly typed language. All core functions will still accept different types. So you basically end up with a mixture of both approaches: Your own functions use a kind of makeshift static typing, whereas the rest of PHP sticks to the classical weak system. I think that's the worst solution of all. Of course you could rewrite the PHP type system itself, and this has actually been done a couple of times. That might be an option. But then again: If you dislike one of the core features of PHP, then why use PHP in the first place? Other languages have had strong typing from the very beginning and do it much better than any PHP hack. I hope that clears it up. No, I'm not against strong typing. To the contrary. But if you want strong typing, PHP isn't really the best choice. Security has very little to do with enforcing certain formats. The point is that the input is treated correctly. For example, if an application is vulnerable to SQL injections, it makes little sense to blame the user for sending us a bunch of characters instead of a number or whatever we expected. This is all just harmless data. It's our fault that the application takes this harmless data and suddenly treats it as an actual SQL query. In other words, it's an interpretation problem, not an input problem. In fact, mistaking data validation for a security feature can end up in a disaster. For example, a perfectly valid e-mail address may very well be used for an SQL injection or cross-site scripting. And a perfectly valid image can contain JavaScript code. And who says that a number is harmless in every context? Validation doesn't help you with this at all. The point is that the e-mail address is actually treated as an e-mail address, regardless of whether or not it's valid. Formal validation is a problem of usability and data correctness, not security – leaving aside a few exceptions. And for that matter, no, I don't think strong typing would suddenly increase the security of PHP applications. We'd still see SQL injections and cross-site scripting and whatnot. Maybe even more, because people might think that type safety magically solves all their security problems.
-
A query in a query loop is almost always the wrong solution. You want a join: SELECT -- something useful, not just "*" FROM stream JOIN users ON stream.stream_username = users.user_username -- you should get rid of those redundant prefixes ORDER BY stream.stream_id DESC ;
-
Hi, you cannot do the empty() check after you've tried to assign the array entry to a variable, because it's already too late then. The index error happens right when you access a nonexistent entry. So you need to wrap the array expression itself into empty(): if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip_address = $_SERVER['HTTP_CLIENT_IP']; } Note that !empty($var) generally makes no sense if $var has been defined previously. This expression checks whether the variable exists and is truthy. Since it does exist, you can jump straight to the truthiness check: if ($var) { ... }
-
You've registered only to complain about me? How flattering. You seem to have a lot of false impressions, though. If you honestly want to talk about my posts or the problems of DevShed, send me a private message.
-
No, I'm talking about the URL. You cannot access $_GET['id'] if there's no “id” parameter in the URL.
-
If you don't want weak typing, then don't use PHP. Trying to turn it into Eldan's Strongly Typed Scripting Language will not work out. Your threads seem to always follow the same pattern: You come up with some weird idea, scream at anybody who tries to turn that into proper PHP, mark your own answer as the best one and come back a few days later. Yeah, well, that doesn't look like a terribly productive hobby.
-
You have no id parameter in the URL. Besides that, your code is wide open to SQL injection attacks. Never drop user input directly into a query string. This can be used to steal or change critical data by manipulating the query. Everything that goes into a query must be quoted and escaped: mysql_query(' SELECT -- something useful, not just "*" FROM class WHERE class_id = "' . mysql_real_escape_string($get_id) . '" '); Besides that, the old MySQL extension is long obsolete and will be removed in one of the next versions. PHP 5.5 already emits tons of error messages when you use it. Didn't you see the big red warnings in the manual? Nowadays, we use PDO.
-
Enforcing specific data types in PHP makes no sense and is, in a way, incorrect. PHP is a weakly typed language, that is, the programmer is generally free to replace any value with an “equivalent” value. For example, PHP doesn't care if you use the integer 123 or the string "123". Both should always have the same effect. The same applies to the boolean true and all truthy values.You may or may not like this, and there are arguments for either type model, but this is how PHP works. It's how people expect it to work. If you insist on getting an actual boolean, you break this fundamental principle and actively work against the language. This creates a lot of confusion and code clutter and simply isn't good programming. The only exception is security-related code. May I ask why you even want this? What's the point of the check?
-
This all looks rather weird. What is this awful strip_tags() supposed to do? Why the "true" and the "false" string? Why all this extra code? It's generally not very useful to concentrate on this one variable and spend your time adding all kinds of questionable extra protection. You should check all input and apply standard protection: You escape the value with mysql_real_escape_string() and wrap the result in quotes. This is done right in the SQL query string: $some_query = ' SELECT ... WHERE some_id = "' . mysql_real_escape_string($some_id) . '" '; Don't forget the quotes. The strip_tags() function has nothing to do with SQL. It's supposed to remove HTML tags, but it works so badly that you usually end up mangling your data.
-
Numbering variables is a bad idea. Just make an array: <?php $name_list = "Mark/Ben/James/Tom"; $names = explode('/', $name_list); echo 'The first name is: ' . $names[0];
-
If only we could search the Internet and find out what other people have to say about this. It's an automated attack from a certain SQL injection tool trying to get information out of your database. This is nothing spectacular, but it's the right time to check your application and make sure everything is secure. Is your software up to date? Are there any known vulnerabilities? Google will, again, help you with that. If you've have written custom scripts, double-check them for vulnerabilities as well.
-
In addition to what Frank already said: It doesn't. The URL points to a subdirectory in the current path. The www.website.com part is not interpreted as a domain. Unfortunately, modern browsers hide all the technical details and accept pretty much any input into the URL bar, so people start to forget how an URL actually looks like. An absolute Internet URL consists of a scheme, a host and a path: https://example.com/foo/bar If you leave out the scheme, you get a relative URL which only consists of a path. So just writing down www.google.com does not get you to Google. It's interpreted as a (relative) path on your own site, which is probably not what you want. So, yes, the “https://” or “http://” is significant. However, you can leave out the scheme if you want to use the current one: //example.com/foo/bar For an HTTPS URL, this would point to https://example.com/foo/bar, for an HTTP URL, it would point to http://example.com/foo/bar.
-
The whole code doesn't make a lot of sense. No offense, but this looks more like guesswork (or copy and paste) than actual programming. You should definitely start using the PHP manual as a reference. This will tell you how the PHP functions and classes actually work. $result is a boolean which indicates whether or not the query was successful. If you want to get the number of rows, you need to get them from $query_login. To get the result set, you must actually fetch it (again from $query_login). Why are you using mysql_real_escape_string()? This function belongs to an entirely different database extension and is completely misplaced here. Why do you insert the $username and $pas into the query string? The whole point of a prepared statement is to not do that. In your case, all the prepare() and execute() doesn't do anything. What's the second argument of the md5() call supposed to do? The second parameter expects a boolean, and this tells the function whether it should return the hash as a binary string or hexadecimally encoded. I'm pretty sure that's not what you want. Is this supposed to be a salt? Then it's not. A salt is a unique random string for a single hash. If you just add a constant string, that doesn't do anything. But salting doesn't help you, anyway, because MD5 hashes can be broken in a matter of minutes on a stock PC. You need an actual password hash algorithm. You must generate a new session ID when the user logs in. Otherwise, PHP will use the old ID which may be known to or even have been set by an attacker. What is $_SESSION['logged'] supposed to do? And why do you store both the user ID and the user name in the session? Every header('Location: ...') call should be followed by an exit statement to stop script execution. Otherwise, the script will happily keep running and can cause all kinds of unwanted behaviour.
-
That looks like a couple of C&P errors. In your if statement on top, you overwrite the same variable twice while not setting the other one at all.
- 2 replies
-
- php
- undefined variable
-
(and 1 more)
Tagged with:
-
You can't apply the bracket syntax to function call expressions unless you have PHP 5.4 or greater (obviously you don't). This doesn't look right, anyway. But I can't tell you without seeing your DB class.