Hi Paul,<br><br>my query was actually generated from the material coming from your own web site! I think I understand better the security issues now.<br><br>I have thought of some other solutions than using a hash table. Having to maintain the hash table can be cumbersome to maintain or not applicable to all situations.
<br><br><span style="font-weight: bold;">Solution 1:</span> use a namespace convention such as<br><br><span style="font-family: courier new,monospace;">&amp;(&quot;namespace_name_&quot; . $sub}(); </span><br><br>But this leaves the call by reference.
<br><br><span style="font-weight: bold;">Solution 2:</span> Use tags to flag which one are the subs which can be called from the outside and build the hashtable &quot;on the fly&quot; at execution time. This seems to be similar to what Catalyst does.
<br><br>for instance:<br><br><span style="font-family: courier new,monospace;">#!/usr/bin/perl</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">use safe_call;</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">sub can_be_called: Callable { ...... }</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">my $sub = $ENV{QUERY_STRING};</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">safe_call($sub);</span><br><br>and in safe_call.pm
<br><br><span style="font-family: courier new,monospace;">my %symcache;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">my @declarations;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">my $identified = 0;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">my %callable;</span><br style="font-family: courier new,monospace;">
<br><span style="font-family: courier new,monospace;">#from Attribute::Handlers</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">sub findsym {<br style="font-family: courier new,monospace;">
</span><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; my ($pkg, $ref) = @_;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $symcache{$pkg,$ref} if $symcache{$pkg,$ref};
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $type ||= ref($ref);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach my $sym ( values %{$pkg.&quot;::&quot;} ) {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (*{$sym}{$type} &amp;&amp; *{$sym}{$type} == $ref) {
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $callable{ *{$sym}{NAME} } = 1;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print &quot;added &quot;, *{$sym}{NAME}, &quot;\n&quot;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $symcache{$pkg,$ref} = \$sym</span>
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
#just stores the declarations for later identification</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">sub MODIFY_CODE_ATTRIBUTES</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">{</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; my ($module, $ref, @attributes) = @_;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; my @other_attr;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; foreach (@attributes) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; if ($_ eq &quot;Callable&quot;) { push @declarations, [ $module, $ref ]; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp; else { push @other_attr, $_;};</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; }</span><span style="font-family: courier new,monospace;"></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; return @other_attr;</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">sub identify</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">{</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; foreach (@declarations) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; findsym @$_[0,1];</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; }</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; $identified = 1;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">sub safe_call {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; identify() unless $identified;
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; $sub_name = shift;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp; if ($callable{$sub_name}) {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; &amp;{$sub_name};</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; else {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp; die &quot;Trying to call unallowed sub $sub_name \n&quot;;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">1;</span><br><br>
I am sure that the above can be improved.<br><br>R.<br><br><div><span class="gmail_quote">On 1/31/06, <b class="gmail_sendername">Paul Fenwick</b> &lt;<a href="mailto:pjf@perltraining.com.au">pjf@perltraining.com.au</a>&gt; wrote:
</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">G'day Raphael,<br><br>Raphael Alla wrote:<br><br>&gt; *#!/usr/bin/perl<br>&gt; my $sub = $ENV{QUERY_STRING};
<br>&gt; &amp;{$sub};<br><br>This code warrants that every subroutine from every module and library you have<br>loaded is perfectly safe to be called without arguments by a hostile attacker.<br>That's a very big warrant.<br>
<br>&amp;{$sub} does not in any way restrict you to your own package.&nbsp;&nbsp;If your<br>subroutine specifies a subroutine in another package (eg:<br>'Dangerous::Package::Kaboom') then that *will* be called.<br><br>To make matters worse, the use of &amp;{...} syntax results in the contents of @_
<br>being passed implicitly to the subroutine, something which not many people expect.<br><br>This code has two fundamental problems, even if there are some circumstances<br>where you may not be able to exploit them:<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* It results in action from a distance.&nbsp;&nbsp;Any subroutine from any<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module could be called, making it *very* hard to determine all<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;possible execution paths.&nbsp;&nbsp;This is not only very bad for security,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it also makes debugging and maintenance difficult.&nbsp;&nbsp;This is reason<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enough to never ever use symbolic references.<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* It is the antithesis to 'deny by default'.&nbsp;&nbsp;Any potential hole<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elsewhere in the program is magnified greatly by the code above.<br><br>I personally would never allow such code past review, let alone run in a<br>security sensitive context.<br><br>All the best,<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Paul
<br><br>--<br>Paul Fenwick &lt;<a href="mailto:pjf@perltraining.com.au">pjf@perltraining.com.au</a>&gt; | <a href="http://perltraining.com.au/">http://perltraining.com.au/</a><br>Director of Training&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Ph:&nbsp;&nbsp;+61 3 9354 6001
<br>Perl Training Australia&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| Fax: +61 3 9354 2681<br>_______________________________________________<br>Melbourne-pm mailing list<br><a href="mailto:Melbourne-pm@pm.org">Melbourne-pm@pm.org</a><br><a href="http://mail.pm.org/mailman/listinfo/melbourne-pm">
http://mail.pm.org/mailman/listinfo/melbourne-pm</a><br></blockquote></div><br><br clear="all"><br>-- <br>Raphael Alla<br>Mitija Australia<br>+61 4 15 678 576<br><br>Premium open source accounting for Australia<br><a href="http://www.thetravelingaccountant.com">
http://www.thetravelingaccountant.com</a>