Topic: "<textarea> XSS vs PHP is not my friend..." (page 1 of 1)

1
Author Post
aceldama
groupmastergroupmastergroupmastergroupmaster
...and as such i need a little assistance. i'm writing an "admin page" for a server running php, though, i've hit a snag. the size of the script is a severe limitation (10kb - 10240bytes), and i want the user to be able to edit pages from the browser using a textarea in a form. the issue arises where i try to uopen a file containing the tag "</textarea>". the form looks like this:
<h3><u>Contents of:</u> /path/file.ext</h3>
<form action="./script.php" method="post" enctype="multipart/form-data">
    <span style="display: inline-block; font-weight: bold; width: 100px;">Edit:</span><br>
    <textarea name="data" cols="100" rows="20" wrap="OFF"><?php file_get_contents("/path/file.ext"); ?></textarea><br>
    <input value="Update" type="submit">
</form>


simple enough, but how do i escape the text so it displays properly (not a problem) and unescape it so it SAVES properly. anyone? and as condensed as possible.
private message
nachtbarjunge
groupmastergroupmastergroupmastergroupmastergroupmastergroupmaster
I am not a PHP expert, but maybe I can help you.

May the files contain untrusted content from untrusted users? If not, maybe it would be the most simple way not to escape anything.

When you don't escape any contents, how are the contents been displayed inside the textarea? Are they displayed as text or rendered as HTML elements?

If you have to escape it, e.g. because you can't trust the content: Do you already know the functions htmlspecialchars(), htmlentities() and html_entity_decode() ?
linkhttp://php.net/manual/en/function.htmlentities.php
linkhttp://www.php.net/manual/en/function.html-entity-decode.php
linkhttp://php.net/manual/en/function.htmlspecialchars.php
Edited by nachtbarjunge on 03.08.2010 12:01:00
private message
Towley
groupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmaster
<?php htmlspecialchars(file_get_contents()); ?>

should do the trick :)
private message Website
aceldama
groupmastergroupmastergroupmastergroupmaster
htmlspecialchars does work, but not when you post it back. i've tried the abovementioned fuctions also, but no joy. it always botches the php file once you update it, even if you just load and post it back, so it's not my coding error that causes the script to fail upon update. :/ thanks though.

EDIT: that should be coding error in the update box.
Edited by aceldama on 04.08.2010 01:06:38
private message
nachtbarjunge
groupmastergroupmastergroupmastergroupmastergroupmastergroupmaster
Maybe you should html-entity-decode() when you save the file. But I think then all characters will be decoded. So when you habe a text with '<' it will not be saved as "&lt;" in the file. So you may use htmlspecialchars() for every output.
Edited by nachtbarjunge on 04.08.2010 08:16:02
private message
aceldama
groupmastergroupmastergroupmastergroupmaster
i've found my problem. for some reason the server escapes all posted data. i worked around it by base64_encode()-ing the data before it's sent and base64_decode()-ing the data before it's witten. as such, no special chars were escaped anymore and everything worked swimmingly. thanks for the help though guys. it's much appreciated.
private message
Towley
groupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmastergroupmaster
By escaping you mean probably magic_quotes_gpc?
This will escape ' with \' on the fly for any Get/Post/Cookie data.

It is recommended to disable magic_quotes_gpc, as this feature is deprecated meanwhile.
If you can not disable magic_quotes, for example when you have no control over php.ini, try this script:

QuoteQuote:

final class GWF_Bootstrap
{
/**
* Unmagicquote a variable.
* This will recursively unmagicquote arrays and only touch strings.
* @param $var Mixed
* @return stripslashed $var
* */
public static function unmagicquoteTypesafe($var)
{
if (is_string($var)) { return stripslashes($var); }
elseif (is_array($var)) { return array_map(array(__CLASS__, 'unmagicquoteTypesafe'), $var); }
return $var;
}

/**
* UnMagicquote GetPostCookie.
* Call me once please.
* */
public static function unmagicquote()
{
# anti magic_quotes_gpc
if (get_magic_quotes_gpc() > 0) {
$callback = array(__CLASS__, 'unmagicquoteTypesafe');
$_GET = array_map($callback, $_GET);
$_POST = array_map($callback, $_POST);
$_REQUEST = array_map($callback, $_REQUEST);
$_COOKIE = array_map($callback, $_COOKIE);
}
# now you should have raw input/output
# have fun # Gizmore ---
}
}
# Call it once
GWF_Bootstrap::unmagicquote(); # anti magic quotes
private message Website
aceldama
groupmastergroupmastergroupmastergroupmaster
thanks for that - it's very elegantly done. very close to what i did as well, but as i said i had to do it really condensed. here's how i did it:

function gv($v){
  $o=(isset($_GET[$v]))?$_GET[$v]:(isset($_POST[$v])?$_POST[$v]:false);
  if(get_magic_quotes_gpc()){$o=(is_string($o))?stripslashes($o):$o;}
  return $o;}


essentially it does the same thing, but doesn't traverse arrays. thanks to everyone for your help.
Edited by aceldama on 08.08.2010 17:26:49
private message

Topic: "<textarea> XSS vs PHP is not my friend..." (page 1 of 1)

1