发信人: jackyz()
整理人: dalasthunder(2002-07-25 06:26:48), 站内信件
|
显示格式化的用户输入
-----------------------------------------------------------------
作者:ying zhang 译者:limodou
此文档描述了如何根据用户的输入安全地显示格式化输出。我们将讨论显示 未经过滤的输出的危险性,然后提出一个显示格式化输出的安全的方法。下载yi ng20000718.zip[http://phprecord.e-chome.net/docs/ying20000718.zip]并且 把它展开到你的web文档目录下。
未过滤输出的危险性
如果你只是简单地得到用户的输入,并且原封不动地将它们显示出来,那样 就可能会破坏你的网页。例如,某些别有用心的人可能在他们的注解中嵌入java script脚本,如:
这是我的注解。<script language="javascript: alert('在这里做一些不好 的事情!')">
即使用户没有什么不良企图,他们也有可能碰巧输入了一些html代码,破坏 页面的布局。例如,你在一个表格中显示用户的输入,当用户输入中包括了一个 错误嵌套的</table>标记,页面显示就被破坏了。只显示无格式文本
最简单的解决方法应该是只在注解中显示无格式文本。使用htmlspecialcha rs() 函数,可以将所有的特殊字符转换成html特殊字符。例如将变成<b& gt;,转换为html标记的文本表示。这就保证了在注解中没有html标记,从而不会 产生不希望的输出。
如果你的访客不介意只是输入无格式文本,这个方法就很好,但是如果你能 够提供给他们一些格式化的功能则就更好了。
使用自定义标记进行格式化
为了实现格式化输出可以为用户提供自已定义的特殊标记。比如可以允许用 户使用[b]...[/b]来表示黑体设置,[i]...[/i]表示斜体设置。可以对它们进行 简单的字符串替换操作:
$output = str_replace("[b]", "", $output);
$output = str_replace("[i]", "", $output);
做得再好一点,允许用户可以加入链接。例如,用户可以在[link="url"].. .[/link]中输入链接,我们将把它转变成合适的<a href="">...语句。这里 不能只使用简单地字符替换,需要使用正则表达式:
$output = ereg_replace('\[link="([[:graph:]]+)"\]', '<a href="\\1">', $output);
如果你对ereg_replace()函数不熟悉的话,这句话的意思就是:
查找所有[link="..."]出现的地方,将其替换成为<a href="...">
[[:graph:]]表示任意非空字符。请查阅手册中的关于正则表达式的详细内容 。
在outputlib.php中的format_output()函数提供了对这些特殊标记的处理, 同时也提供了对其它几个特殊标记的处理。通用的算法是:
对输出文本调用htmlspecialchars()函数来转换所有的特殊字符为html的特殊字 符
对自定义的标记系统地进行字符串替换或正则式替换
-------------------------------------------------------------------
<?php
function format_output($output)
{
/***********************************************************
* 处理原始的字符串($output)并且进行格式化处理,使用特殊的与html
* 相似的标记
************************************************************/
$output = htmlspecialchars(stripslashes($output));
/* 新的段落 */
$output = str_replace('[p]', '<p>', $output);
/* 黑体 */
$output = str_replace('[b]', '', $output); $output = str_replace ('[/b]', '', $output);
/* 斜体*/
$output = str_replace('[i]', '', $output); $output = str_replace ('[/i]', '', $output);
/* 预览格式 */
$output = str_replace('[pre]', '<pre>', $output); $output = str_rep lace('[/pre]', '</pre>', $output);
/* 缩进块 (blockquote) */
$output = str_replace('[indent]', '<blockquote>', $output); $output = str_replace('[/indent]', '</blockquote>',
$output);
/* 锚点*/
$output = ereg_replace(
'\[anchor="([[:graph:]]+)"\]',
'<a name="\\1">', $output);
/* 链接,注意我们打算阻止Javascript出现在链接中 */
$output = str_replace('[link="javascript',
'[link=" javascript', $output);$output = ereg_replace(
'\[link="([[:graph:]]+)"\]',
'<a href="\\1">', $output);$output = str_replace('[/link]', ' ', $output);
return nl2br($output);
}
?>
-------------------------------------------------------------------
一些注意事项:
记得在调用完tmlspecialchars()之后而不是之前执行字符串替换操作,否则如果 你在后面才调用htmlspecialchars(), 那么在前面你所做的将自定义标记转换为 HTML的特殊标记的工作将付之东流。
记得在你的替换字符串中查找HTML的特殊标记,例如要把"(双引号)看成" ;,因为在前面已经被转换成这样了。可以查阅一下手册中关于htmlspecialchar s()函数的说明。
nl2br()函数将换行符转换为<br>标记,请再次确认这是在htmlspecialchars()之 后被调用的,而不是前面。
当转换[links=""]为<a href="">时,你必须保证不让别人在其中插入javascrip t脚本。一个简单的方法就是将 [link="javascript改成[link=" javascript,这 种方法就不会匹配链接模式,并且它将被按原样输出。
outputlib.php
装入test.php脚本来看一下format_output()函数是如何工作的。首先在文本 框中输入下面的文本:
正常的HTML标记不能使用,可以使用特殊标记进行替换:
- 这是 [b]黑体[/b]
- 这是 [i]斜体[/i]
- 这是 [link="http://www.phpbuilder.com"]一个链接[/link]
- 这是 [anchor="test"]一个锚点,和一个 [link="#test"]链接[/link] 到指定 的锚点
[p]这是一个段落分隔
[pre]这是一个预览格式文本[/pre]
[indent]这是一个缩进文本[/indent]
示范结束。
到目前只有少量的标记可以使用--你可以随意增加认为合适的标记。
结论
这篇文章讨论了显示未经格式化的用户输入的危险性,并且提供了一个通过 自定义标记来显示格式化后的用户输入信息的方法。这个方法可以用在任何想要 接收用户输入的地方,例如:
留言薄
用户注解
系统公告
等等
转自phpbuilder.com
-----------------------------------------------------------------
来自:http://phprecord.126.com
作者:limodou
// limodou出品,必属佳品.呵呵.
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.141.204.221]
|
|