|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-09-27 11:20 UTC] sird at rckc dot at
Description: ------------ Taken from: http://bugs.php.net/bug.php?id=48230 > > Description: > ------------ > xml_utf8_decode function incorrectly decode. > > Reproduce code: > --------------- > <?php > $ill=chr(0xf0).chr(0xc0).chr(0xc0).chr(0xa7); > $ill=addslashes($ill); > echo utf8_decode("$ill"); > echo htmlspecialchars ($ill,ENT_QUOTES,"utf-8" ); > ?> > > Expected result: > ---------------- > it will output a "'" incorrectly. > > Actual result: > -------------- > it will output a "'" incorrectly. This is actually a PHP security vulnerability. Timeline: * Reported by root@80sec.com: May 11 * Discovered by webmaster@lapstore.de: June 19 * Discovered by Giorgio Maone / Eduardo Vela: July 14 * Reported and Fixed on PHPIDS: July 14 * Microsoft notified of a XSS Filter bypass: July 14 * Fixed XSS Filter bypass on NoScript 1.9.6: July 20 * Vulnerability disclosed on BlackHat USA 2009: July 29 * Added signature to Acunetix WVS: August 14 References: * http://www.blackhat.com/presentations/bh-usa-09/VELANAVA/BHUSA09-VelaNava-FavoriteXSS-SLIDES.pdf * http://www.acunetix.com/blog/web-security-articles/security-risks-associated-with-utf8_decode/ * http://us2.php.net/manual/en/function.utf8-decode.php#83935 * http://bugs.php.net/bug.php?id=48230 * http://noscript.net/changelog Read the references for further details. Reproduce code: --------------- <?php echo utf8_decode(addslashes("\xf0\xc0\xc0\xa7 or 1=1-- -")); // more code in references, check the slides and the acunetix blog ?> Expected result: ---------------- ? or 1=1-- - Actual result: -------------- ' or 1=1-- PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
I disagree.. how slow can it be to add 2 bit operations.. } else if (c < 0x800) { change to } else if (c < 0x800) { if ( (s[1]&0xC0!=0x80) ){ // this is a new operation newbuf[(*newlen)++] = '?'; // this are not new operations pos--; // this are not new operations s++; // this are not new operations continue; } } Besides, considering all real implementations do what the spec say they should do (it's not validate it's valid UNICODE, is that UNICODE says that the algorithm SHOULD do the check).. not doing it on PHP is just nuts.oh, my mistake: else if (c < 0x800) { newbuf[(*newlen)++] = (0xc0 | (c >> 6)); newbuf[(*newlen)++] = (0x80 | (c & 0x3f)); } should be: else if (c < 0x800) { if ( (s[1]&0xC0!=0x80) ){ newbuf[(*newlen)++] = '?'; }else{ newbuf[(*newlen)++] = (0xc0 | (c >> 6)); newbuf[(*newlen)++] = (0x80 | (c & 0x3f)); } }Oh, duh! I'm reading the wrong function.. :( Sorry if(pos-2 >= 0 || s[1]&0xC0!=0x80) { c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63); } else { c = '?'; }