|
I just stick this near the beginning of my script (I route everything on a site through one script) and then get on with things as normal.php:<? // Kill magic quotes because it's stupid. if (get_magic_quotes_gpc()) { function stripslashes_deep($value) { if (is_array($value)) { $value = array_map('stripslashes_deep', $value); } else { $value = stripslashes($value); } return $value; } $_POST = array_map('stripslashes_deep', $_POST); $_GET = array_map('stripslashes_deep', $_GET); $_COOKIE = array_map('stripslashes_deep', $_COOKIE); $_REQUEST = array_map('stripslashes_deep', $_REQUEST); } ?>
|
# ? Jun 12, 2010 12:33 |
|
|
# ? Jun 7, 2024 02:54 |
|
MrMoo posted:It looks like mb_check_encoding() would be a good choice, The comments on that manual page make me unsure what to think. They suggest that the commenters think that the function is lacking, but I don't feel like I know enough about this stuff to evaluate their objections. I feel like I'm not able to work out what I need to do to make sure my app is safe.
|
# ? Jun 12, 2010 13:13 |
|
Pookster posted:I just stick this near the beginning of my script (I route everything on a site through one script) and then get on with things as normal. FYI, you can use $_POST = stripslashes_deep($_POST); since your function already does an array_map.
|
# ? Jun 12, 2010 15:51 |
|
DarkLotus posted:FYI, you can use $_POST = stripslashes_deep($_POST); since your function already does an array_map. That's very true. Luckily I haven't had to use servers with magic quotes enabled for a while so this code wasn't even getting called.
|
# ? Jun 13, 2010 10:46 |
|
Hammerite posted:For information, and in relation to the discussion we were having about sanitising user input, this is the function I have adopted for sanitising user input that is expected to be of type string. (PHP_MAJOR_VERSION is defined elsewhere.) No offense, but this is a pretty good example of how not to write code. So much of this should be reformatted or otherwise changed.
|
# ? Jun 14, 2010 07:49 |
|
isagoon posted:No offense, but this is a pretty good example of how not to write code. So much of this should be reformatted or otherwise changed. I'd love to respond to this comment, but you seem to have gone out of your way to provide absolutely no specific criticisms whatsoever.
|
# ? Jun 14, 2010 12:33 |
|
Hammerite posted:I'd love to respond to this comment, but you seem to have gone out of your way to provide absolutely no specific criticisms whatsoever. It confuses me a bit but maybe its my lack of understanding of PHP than your code. Here's some thoughts though: $flags = 0 should be $flags=null if you want it to be optional, otherwise $flags becomes a constant (0). Your ifs use inconsistent notation: "and" "&". Shouldn't ands be && or is & something specific. $flags & STRING_TO_UPPERCASE will always equal true: you have defined both and your if isn't looking for a specific value. $flags & STRING_TO_LOWERCASE will never be called because of the above. Why would you remove new lines and not replace them with some identifier so that the formatting matches when the string is drawn from the database? I know this pisses off users just from seeing people's Facebook status complaining about the fact line breaks used to be removed. Again, I'm hobbyist amateur with PHP so these are just things I've picked up as contradictory to my knowledge/experience.
|
# ? Jun 14, 2010 13:07 |
|
gwar3k1 posted:Your ifs use inconsistent notation: "and" "&". Shouldn't ands be && or is & something specific. & is "bitwise and". A call to this function might look like this: $mystring = sanitise_string(@$_POST['mystring'], STRING_TO_UPPERCASE | STRING_ESCAPE_HTML) STRING_TO_UPPERCASE is in binary ...000001 and STRING_ESCAPE_HTML is in binary ...100000, so bitwise or-ing them together with | yields ...100001. Now, the conditions $flags & STRING_TO_UPPERCASE and $flags & STRING_ESCAPE_HTML are true, but $flags & STRING_STRIP_NEWLINES is false. Additionally, you're mistaken when you say that quote:$flags & STRING_TO_UPPERCASE will always equal true bearing in mind that you were under the impression that "&" means the same thing as "&&", you're incorrect because if $flags is equal to zero (as per its default value), $flags && STRING_TO_UPPERCASE will be false (zero interpreted as a Boolean is false).
|
# ? Jun 14, 2010 13:27 |
|
Thanks for the explaination.
|
# ? Jun 14, 2010 13:37 |
|
gwar3k1 posted:Why would you remove new lines and not replace them with some identifier so that the formatting matches when the string is drawn from the database? I know this pisses off users just from seeing people's Facebook status complaining about the fact line breaks used to be removed.
|
# ? Jun 14, 2010 13:40 |
|
isagoon posted:No offense, but this is a pretty good example of how not to write code. So much of this should be reformatted or otherwise changed. You know, I looked back at that function and decided I didn't like the way it was laid out very much. I have no idea what your objections are to it, but I reformatted it to be more pleasing. Or at least, more pleasing to me. I have no idea where you are coming from. code:
|
# ? Jun 14, 2010 14:16 |
|
Hammerite posted:You know, I looked back at that function and decided I didn't like the way it was laid out very much. I have no idea what your objections are to it, but I reformatted it to be more pleasing. Or at least, more pleasing to me. I have no idea where you are coming from. Ok, allow me to explain. First off, $x = (string)$x; is unneeded. PHP will automatically cast the argument to a string. Second, single sentence blocks should not be braced. Third, but nitpick, is that you may want to use && instead of AND. Either will work, but most everybody prefers to use &&. Since you aren't doing anything with $x after your if statement, you could just return each one of those right then and there instead of reassigning it. The bitwise stuff is fine. The logic of the function is sound, but formatting is also an important. A lot of PHP coders don't seem to follow good formatting rules. isagoon fucked around with this message at 16:33 on Jun 14, 2010 |
# ? Jun 14, 2010 16:27 |
|
isagoon posted:Ok, allow me to explain. quote:Second, single sentence blocks should not be braced. quote:Third, but nitpick, is that you may want to use && instead of AND. Either will work, but most everybody prefers to use &&. quote:Since you aren't doing anything with $x after your if statement, you could just return each one of those right then and there instead of reassigning it.
|
# ? Jun 14, 2010 16:37 |
|
Having an issue with an array and a foreach loop, trying to figure out whats going on...php:<? print_r($arrFieldData['options']); $intCount = '0'; foreach ($arrFieldData['options'] as $strOptionValue => $strOptionDesc) { if ($strOptionValue == 'default') { $arrOptionData['default']['value'] = $strOptionValue; $arrOptionData['default']['desc'] = $strOptionDesc; } $arrOptionData[$intCount]['value'] = $strOptionValue; $arrOptionData[$intCount]['desc'] = $strOptionDesc; $intCount++; } print_r($arrOptionData);?> php:<? Array ( [default] => MacBook [0] => MacBook (Unibody) [1] => MacBook Pro [2] => MacBook Pro (Unibody) [3] => MacBook Air [4] => iBook [5] => PowerBook G4 ) ?> php:<? ( [default] => Array ( [value] => 0 [desc] => MacBook (Unibody) ) [0] => Array ( [value] => default [desc] => MacBook ) [1] => Array ( [value] => 0 [desc] => MacBook (Unibody) ) [2] => Array ( [value] => 1 [desc] => MacBook Pro ) [3] => Array ( [value] => 2 [desc] => MacBook Pro (Unibody) ) [4] => Array ( [value] => 3 [desc] => MacBook Air ) [5] => Array ( [value] => 4 [desc] => iBook ) [6] => Array ( [value] => 5 [desc] => PowerBook G4 ) ) ?> edit. And it only happens if the very first value in $arrFieldData['options'] is the default... otherwise works as I intended i am not zach fucked around with this message at 16:56 on Jun 14, 2010 |
# ? Jun 14, 2010 16:42 |
|
Hammerite posted:You might well be right, but making sure it's a string when it comes out the other end of the function gives me peace of mind. isagoon fucked around with this message at 17:01 on Jun 14, 2010 |
# ? Jun 14, 2010 16:55 |
|
i am not zach posted:Having an issue with an array and a foreach loop, trying to figure out whats going on... Try changing if ($strOptionValue == 'default') to if ($strOptionValue === 'default'). I think you're unintentionally getting a result of "true" from the comparison when PHP tries to compare a non-numeric string to integer 0. isagoon posted:You aren't making sure of anything. PHP will cast it to a string no matter what it starts out as, and those function calls will return a string no matter what. $x = sanitise_str(@$_GET['something_or_other'], STR_NO_TRIM | STR_NO_STRIP_CR); and magic_quotes_gpc is off? Then it'll pass through the function unchanged. And the input might indeed happen not to be a string if I'm using it on GET or POST data. isagoon posted:As you wish. For that code snippit, you could just return immediately
|
# ? Jun 14, 2010 17:14 |
|
Hammerite posted:Try changing if ($strOptionValue == 'default') to if ($strOptionValue === 'default'). I think you're unintentionally getting a result of "true" from the comparison when PHP tries to compare a non-numeric string to integer 0. That was it... thanks
|
# ? Jun 14, 2010 17:19 |
|
isagoon posted:As you wish. For that code snippit, you could just return immediately The entire point of the snippet is to process the input in one or more ways depending on the flags. The operations aren't exclusive, so you can't return until you've iterated through all the possible operations that could be performed on that string. corgski fucked around with this message at 20:03 on Jun 14, 2010 |
# ? Jun 14, 2010 19:58 |
|
isagoon posted:Second, single sentence blocks should not be braced. No, no no no! This is terrible practice, as it (amongst other reasons) makes it less readable amongst other code, doesn't allow for brace matching, and doesn't allow for additional statements to be added in the future. It goes against pretty much every coding standard PHP has. Drupal, evolt, Zend, PEAR, Some dude, and even PHPBB all document the requirement for braces on one-statement if blocks. PHP itself doesn't have a coding standard a la the Java standard, but between them, those above provide a pretty comprehensive list of dos-and-donts, most of which tally up.
|
# ? Jun 14, 2010 21:17 |
|
Hammerite posted:Try changing if ($strOptionValue == 'default') to if ($strOptionValue === 'default'). I think you're unintentionally getting a result of "true" from the comparison when PHP tries to compare a non-numeric string to integer 0.
|
# ? Jun 15, 2010 00:25 |
|
isagoon posted:If I was about to use a function named sanitise_str(), I would expect to be able to pass any user input to it and get a string as output. If you don't include the typecast, then the return value could be an array. If I'm expecting a string and I get an array, this could very well lead to an exploit. And why would anyone spend the time to decide whether a typecast is superfluous? Even if it is, you might make a change to the code later to something that would require that typecast.
|
# ? Jun 15, 2010 01:09 |
|
barbarianbob posted:If I was about to use a function named sanitise_str(), I would expect to be able to pass any user input to it and get a string as output. If you don't include the typecast, then the return value could be an array. If I'm expecting a string and I get an array, this could very well lead to an exploit. I really don't understand this. It isn't permissible in any other language, why should you expect valid output when you input something totally unexpected? If you code has an exploit in such a situation, you are doing something very, very, very wrong.
|
# ? Jun 15, 2010 02:21 |
|
isagoon posted:I really don't understand this. It isn't permissible in any other language, why should you expect valid output when you input something totally unexpected?
|
# ? Jun 15, 2010 02:36 |
|
Hammerite posted:Well, the thing is, if the function is being used to tackle user-supplied input, you're opening it up to input that is totally unexpected. Given that the input is received from a user who's using your site faithfully, you have nothing to worry about. If you're receiving input from a malicious user, it's as well to make sure your public-facing scripts coerce the input to something harmless and do their job as well as possible. It's not as though doing a simple typecast adds a lot of work for the server to do. No, it doesn't. The user cannot supply anything but a string. The only way a user could supply an array is if he used a script to POST (or GET, for that matter) an array of strings. Remember, there is a difference between a string representation of an object (RE: Serialization) and an actual data type.
|
# ? Jun 15, 2010 02:51 |
|
Argh, quote != edit
|
# ? Jun 15, 2010 02:52 |
|
isagoon posted:No, it doesn't. The user cannot supply anything but a string. The only way a user could supply an array is if he used a script to POST (or GET, for that matter) an array of strings. Remember, there is a difference between a string representation of an object (RE: Serialization) and an actual data type. If a user sends the request script.php?foo=a&foo=b then $_GET["foo"] will be an honest-to-god array. This is trivial for a user to do, and doesn't require any script or programming or anything on the user's end. If the script is expecting $_GET["foo"] to be a string, then bad things could happen because various operations will not perform as the programmer expected. Explicitly casting it to a string removes this possibility.
|
# ? Jun 15, 2010 04:45 |
|
ShoulderDaemon posted:If a user sends the request script.php?foo=a&foo=b then $_GET["foo"] will be an honest-to-god array. This is trivial for a user to do, and doesn't require any script or programming or anything on the user's end. If the script is expecting $_GET["foo"] to be a string, then bad things could happen because various operations will not perform as the programmer expected. Explicitly casting it to a string removes this possibility. What, I always had to do script.php?foo[]=a&foo[]=b to get $_GET['foo']=array('a','b')... did things change? I know I've seen Perl work like the above...
|
# ? Jun 15, 2010 05:36 |
|
FeloniousDrunk posted:What, I always had to do script.php?foo[]=a&foo[]=b to get $_GET['foo']=array('a','b')... did things change? I know I've seen Perl work like the above... It's possible I'm misremembering and you're correct; it's been more than a while since I had to use PHP.
|
# ? Jun 15, 2010 05:38 |
|
ShoulderDaemon posted:It's possible I'm misremembering and you're correct; it's been more than a while since I had to use PHP. I always hated that PHP wouldn't do that, but I guess it was just too hard to implement. I'll have to give it a shot tomorrow on the 5.3 machine.
|
# ? Jun 15, 2010 05:42 |
|
FeloniousDrunk posted:What, I always had to do script.php?foo[]=a&foo[]=b to get $_GET['foo']=array('a','b')... did things change? I know I've seen Perl work like the above... You're right, that should produce an array, which is what I have been saying. A better alternative to simply casting would be to check if it's an array and return false or throw an exception.
|
# ? Jun 15, 2010 06:13 |
|
isagoon posted:You're right, that should produce an array, which is what I have been saying. No you haven't! You've been insisting all along that the typecast is redundant and will make no difference, and that "the user cannot supply anything but a string" (your words). The best sense I can make of your posts is that you're making some academic point about how if the user sends an array then it will be serialised in the form of a string, which doesn't have any bearing on the fact that it'll be an array by the time my script sees it. Now you're recognising that it can be an array, but saying "err, yeah it could be an array, but you should do something different to deal with the possibility anyway"? As if it matters which of various options I use to deal with (presumably) malicious input, provided that it's made safe.
|
# ? Jun 15, 2010 06:58 |
|
Hammerite posted:No you haven't! You've been insisting all along that the typecast is redundant and will make no difference, and that "the user cannot supply anything but a string" (your words). The best sense I can make of your posts is that you're making some academic point about how if the user sends an array then it will be serialised in the form of a string, which doesn't have any bearing on the fact that it'll be an array by the time my script sees it. Now you're recognising that it can be an array, but saying "err, yeah it could be an array, but you should do something different to deal with the possibility anyway"? As if it matters which of various options I use to deal with (presumably) malicious input, provided that it's made safe. Ok, we're talking about two different things there. First off, if you input an array into a function that wants a string, you will get "Array". There is no way to find an exploit off this. An array tostring is just "Array". Second, if you want to catch that condition, you shouldn't just blindly cast it to a string. You will get the same as above. Try it for yourself if you don't believe me. If you want to catch it, you should be specifically checking if it's an array. Regardless of if you manually cast it to a string, you will still get "Array".
|
# ? Jun 15, 2010 15:31 |
|
isagoon posted:Ok, we're talking about two different things there. If it is one of PHP's builtin functions, yes, that is true. If I want to pass the supposedly sanitised variable to some function (whether written by me or someone else) that for whatever reason accepts a string or an array, then I probably will not be satisfied with the results of passing it an array when I'm under the impression that I'm passing it a string. isagoon posted:Second, if you want to catch that condition, you shouldn't just blindly cast it to a string. You will get the same as above. Try it for yourself if you don't believe me. If you want to catch it, you should be specifically checking if it's an array. I know that if you cast an array to string, you get "Array". I'm not sure why this matters; I only want to make the input safe, not make sense of it. I'm also not sure why I'd reject a simple statement (the typecast) that should work in every single contingency in favour of one that would only deal with the specific case where the supplied value is an array, and would leave a (hypothetical) other exploit open. After all, gently caress, we both know PHP itself is full of holes and bad design decisions, so how confident can you be that that would cover every possible exploit? Why wouldn't you go for the simple option that provides peace of mind? This is what I don't understand about the position you're arguing.
|
# ? Jun 15, 2010 16:35 |
|
You could just return (string)$x. I think that makes it a lot more obvious to someone reading it that the function is guaranteed to return a string, especially if they're not familiar with the behavior of the PHP built-ins. edit: quote:I know that if you cast an array to string, you get "Array". I'm not sure why this matters It sort-of matters because as long as you pass something (that might be an array) through one (probably any - I can't see it from the post editing mode) of the PHP functions you're using in that sanitizer, that your input will be mangled into a string automagically before that function even operates on it, so it's useless to do it yourself. Doing useless things can be confusing to other people who might read your code unless there's a policy in place to do them or something. My bike shed would be orange. Munkeymon fucked around with this message at 17:10 on Jun 15, 2010 |
# ? Jun 15, 2010 16:53 |
|
Rewinding a bit, as I didn't see this addressed.Hammerite posted:Should I be checking user input to make sure it is well-formed UTF-8? Is there a builtin function for that? What is the worst-case scenario if I fail to screen for bad UTF-8? This is a derived and cleaned up version of what we use on $_GET, $_POST and $_REQUEST at work: php:<? /** * Clean an array of null values and corrupt UTF-8 sequences * @return array **/ function clean_input_corruption($input) { foreach($input as $k => $v) { if(is_array($v)) { $input[$k] = clean_input_corruption($v); continue; } // end if $input[$k] = iconv('UTF-8', 'UTF-8//IGNORE', str_replace("\r\n", "\n", $v)); $input[$k] = preg_replace('/\0/', '', $v); } // end foreach return $input; } // end clean_input_corruption?> This works for us because: 1) We never get input that contains newlines in which we'd want to preserve carriage returns. 2) If the user submits broken UTF-8 to us, we don't care that the default behavior of iconv is to stop on error thus possibly truncating the string at the break. 3) We never get input from users that contains null.
|
# ? Jun 15, 2010 21:27 |
|
quote:Typecasting to string argument The thing is, php's built-in functions are inconsistent a lot of the time. Some string functions force a typecast to the string "Array" but others (such as the str_replace calls) allow an array as the input and then return an array. If you use the flags for sanitize_str that run only the str_replace's (or match none of the if conditions at all), then your output can be an array and not a string. My point assumes that the programmer never wants an array as output, since if I was expecting input as an array, I'd loop through it and run this function separately on each of the elements. I'm assuming the following phpdocs: code:
|
# ? Jun 15, 2010 22:01 |
|
Thanks for the response McGlockenshire. I propose to additionally screen user input using the following function: php:<? function check_utf8_validity ($x) { // Based on code posted to the PHP manual page for mb_check_encoding() by // "javalc6 at gmail dot com" on 24/12/2009. Checks that a string is valid // UTF-8; also checks that it contains no non-printing characters except // for 09 (TAB / horizontal tab), 0A (LF / line feed), and // 0D (CR / carriage return). Returns true if input satisfies these // criteria, false otherwise. $x = (string)$x; $length = strlen($x); for ($i=0; $i<$length; $i++) { $c = ord($x[$i]); if ( $c > 126 ) { if ( $c > 244 ) { return false; } else if ( $c > 239 ) { $bytes = 4; } else if ( $c > 223 ) { $bytes = 3; } else if ( $c > 193 ) { $bytes = 2; } else { return false; } if ( $i + $bytes > $length ) { return false; } while ( $bytes > 1 ) { $i++; $b = ord($x[$i]); if ( $b < 128 or $b > 191 ) { return false; } $bytes--; } } else if ( $c < 32 and $c != 9 and $c != 10 and $c != 13 ) { return false; } } return true; } ?> Hammerite fucked around with this message at 01:01 on Jun 16, 2010 |
# ? Jun 15, 2010 22:56 |
|
I am having issues getting a function to work that parses some bbcode into HTML. The BBcode: code:
code:
code:
|
# ? Jun 15, 2010 23:05 |
|
Trinitrotoluene posted:I know %22 is ASCII for " but why the hell is it invading my url and malforming it!! I do not know why the " is being turned into %22. I do know that you could stop it being part of the matched subexpression by modifying the "search" regex to '@\[url\s*=\s*"?([^\]\s]*?)"?\s*\](.*?)\[\/url\]@si' Unfortunately that means that e.g. code:
|
# ? Jun 15, 2010 23:25 |
|
|
# ? Jun 7, 2024 02:54 |
|
Hammerite posted:Unfortunately that means that e.g. You can use a match and a backreference to allow double quotes, single quotes, or no quotes: code:
|
# ? Jun 15, 2010 23:27 |