免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3225 | 回复: 13
打印 上一主题 下一主题

关于Perl的tainted模式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-16 21:57 |只看该作者 |倒序浏览
前几天跟Apile谈起了cgi的安全问题,并谈到了tainted模式。回去后偶查了一些关于tainted的资料,并看到一个如何判断某个变量是否tainted的函数如下:

sub is_tainted{
   my $var=shift;
   my $blank=substr($var,0,0);
   return not eval {eval "1 || $blank" || 1};
}


这个函数让偶郁闷了半天,于是在mailing list上发贴求教。perlmonk的Jeff很热心的回答了偶的问题,引用如下:

If a variable is tainted, then any substring of that variable is also
tainted.  In addition, it is illegal to eval() any string that is tainted.
The inclusion of a tainted string inside another string makes that whole
string tainted.

Therefore:  if $var is tainted, the $blank will also be tainted (even
though it's a substring of zero characters).  If $blank is then tainted,
then the code

  eval { eval "1 || $blank" || 1 }

will return false (since the eval { ... } catches fatal errors, and the
eval "1 || $blank" raises a fatal error because $blank is tainted), and
therefore,

  return not eval { eval "1 || $blank" || 1 };

returns true, stating that $var is indeed tainted.  If $var wasn't
tainted, then

  eval "1 || $blank" || 1

returns 1, and

  return not eval { 1 }

returns false, stating that $var wasn't tainted.

*whew*

Frankly, I find the 'eval "1 || $blank" || 1' silly, since the whole
reason the '... || 1' is needed is since $blank is a blank string and the
code '1 || ' is invalid Perl.  Long story short, I'd have written:

  sub is_tainted {
    return not eval { eval 1 . substr($_[0], 0, 0) };
  }

It's much more concise.  If $_[0] isn't tainted, then

  not eval { eval 1 . substr($_[0], 0, 0) }
  ->
  not eval { eval 1 }
  ->
  not eval { 1 }
  ->
  not 1
  ->
  false

whereas if $_[1] is tainted, then the eval { ... } returns false since a
fatal error is raised because

  eval 1 . substr($_[0], 0, 0)

is illegal if $_[0] is tainted.



偶仍有所不明,于是再问Jeff:

1)eval "1 || $blank";
When $blank is tainted,the $blank is false,but "1 || $blank" should return
true,because "true || false" will return true always.Isn't it?

2)why to call eval 2 times here?


Jeff回答:

If $var is tainted, then even though $blank is an empty string, it's
tainted also.  That means the string "1 || $blank" (which is really just
"1 || " (which if it WERE eval'd would be a syntax error!)) is tainted by
association with $blank.  And eval($some_tainted_string) is a fatal error.
If we didn't have the eval { ... } around the eval($tainted_string), the
Perl application would die with the "Insecure dependecy..." error message.
The outer eval { ... } catches this error.

So, when $blank is tainted, the eval "1 || $blank" doesn't even get as far
as executing the code inside it.  It realizes it's ABOUT to eval() tainted
code, and dies; and that's what the outer eval { ... } is there for.


终于弄明朗了这个哈,大家也可看一下。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2005-11-17 08:45 |只看该作者
谢谢仙子..
虽然大概知道tainted mode是怎麽回事...也知道他很复杂...
曾经我也在CGI里面打开-T..不过一堆fatal error..让我决定把他关了...

不过用这个subroutine倒不失为一个判断tainted variable..好方法..

好久没看perl的书了......

论坛徽章:
0
3 [报告]
发表于 2005-11-17 09:02 |只看该作者
原帖由 apile 于 2005-11-17 08:45 发表
谢谢仙子..
虽然大概知道tainted mode是怎麽回事...也知道他很复杂...
曾经我也在CGI里面打开-T..不过一堆fatal error..让我决定把他关了...

不过用这个subroutine倒不失为一个判断tainted variable..好方法 ...


是哦,偶也是因为debug麻烦,一直不用-T的,以后为secure起见,也许该试着打开它,

论坛徽章:
0
4 [报告]
发表于 2005-11-17 09:43 |只看该作者
Therefore:  if $var is tainted, the $blank will also be tainted (even
though it's a substring of zero characters).  If $blank is then tainted,
then the code


什么样的数据是被污染的?可否举例说明一下,
  1. substr($_[0], 0, 0)
复制代码

这个到底返回什么,以至于eval之后竟会有语法错误?
不解中……

论坛徽章:
0
5 [报告]
发表于 2005-11-17 09:54 |只看该作者
原帖由 怒剑狂啸 于 2005-11-17 09:43 发表


什么样的数据是被污染的?可否举例说明一下,
  1. substr($_[0], 0, 0)
复制代码

这个到底返回什么,以至于eval之后竟会有语法错误?
不解中……


什么样的数据是被污染的?

任何从脚本外部接受过来的数据,都是tainted的。例如从STDIN,Socket,file handle接受的数据,都被称为tainted的。而且tainted属性是可传递的,也就是说,某个变量tainted了,那么由该变量计算或派生的其他变量也是tainted的。



substr($_[0], 0, 0)

什么也不返回哦,它是个0长度的string.这里返回什么没有意义,因为它是tainted变量的子串,所以它本质上也是tainted的。至于语法错误,是因为在-T模式下,eval接受到任何tainted变量,都会引起fatal error而引起die发生。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
6 [报告]
发表于 2005-11-17 11:04 |只看该作者
原帖由 怒剑狂啸 于 2005-11-17 09:43 发表


什么样的数据是被污染的?可否举例说明一下,
  1. substr($_[0], 0, 0)
复制代码

这个到底返回什么,以至于eval之后竟会有语法错误?
不解中……

tainted mode下,数据要让他没被污染,要用
$untainted_variable = $var =~/(w+)/;
也可以
$untainted_variable = $var =~/(.*)/;
只是这样子就失去-T的本意了...

tainted 简单的说就是不是代码内给值的...
而是从其他地方透过I/O进来给值的都算tainted...

论坛徽章:
0
7 [报告]
发表于 2005-11-17 11:07 |只看该作者
因为不怎么用perl写cgi,以前看到perl安全这一节就草草翻翻,一直觉得变量的污染模式就是指变量中含有不安全的代码,犯了一个常识性的错误,呵呵,谢谢仙子!

论坛徽章:
0
8 [报告]
发表于 2005-11-17 11:19 |只看该作者

  1. $untainted_variable = $var =~/(.*)/;
复制代码

apile兄,这样做有什么作用么?难道是去除$var中的换行符以及换行符后的内容么?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
9 [报告]
发表于 2005-11-17 11:27 |只看该作者
其实tainted就是强迫你检查所有的variable..只要不是自己产生的...
一定要透过regular expression去产生untainted variable..
上面.*其实只是在骗-T...我有用regular expression..其实一点更动也没有...
上面.*可以改成..例如叁数一定要是数字...\d+....
可以有效解决sql injection或system碰到 ; 的问题....
\n

论坛徽章:
0
10 [报告]
发表于 2005-11-17 12:02 |只看该作者
哦,其实就是给programmer一个提示,要check一下,确保外部输入没有不安全的代码,改天再好好看看,谢谢apile兄!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP