Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Is Module::SafeVersion a Waste of Time?

by Ovid (Cardinal)
on Apr 24, 2006 at 20:02 UTC ( #545374=perlmeditation: print w/replies, xml ) Need Help??

Most code which attempts to find the version number of a given module either uses a naive regex, uses "eval" on the version line, or loads the module and calls $module->VERSION.

I'm writing Module::SafeVersion which attempts to do this correctly, but it may never get released. I'm employing a combination approach of using a rather complicated regex along with some "cleanup" code to handle the majority of cases. Currently it properly extracts about 98% of the versions of modules installed on my laptop. However, the special cases are significant and I can't ignore them.

I can try to continually expand the regex and the cleanup code, but I'm sadly beginning to think that what needs to be done is to build in special cases for those modules which have jumped through ridiculous hoops to generate their version numbers. Let's look at some examples:

# From SOAP::Lite $VERSION = sprintf("%d.%s", map {s/_//g; $_} q$Name: release-0_60-publ +ic $ =~ /-(\d+)_([\d_]+)/) # From SQL::Abstract $VERSION = do { my @r=(q$Revision: 1.20 $=~/\d+/g); sprintf "%d."."%02 +d"x$#r,@r }; # From CPAN my $VERSION = sprintf "%.2f", substr(q$Rev: 245 $,4)/100;

(It should also be pointed out that there are plenty of problems with this approach, too. Particulary since it will never be 100% successful).

Schwern argued that this entire module is the wrong approach. Specifically, if eval'ing a version string is a problem, this implies that you already have bad code on your box and the version string is the least of your problems. PAUSE apparently runs in a chroot jail, so the only folks likely to be bitten by a version string attack would be smoke testers. Thus, if I have code on my box, it should automatically be viewed as trusted. Thoughts?


New address of my CGI Course.

Replies are listed 'Best First'.
Re: Is Module::SafeVersion a Waste of Time?
by itub (Priest) on Apr 24, 2006 at 20:18 UTC
    When writing the AnnoCPAN code, I decided to ignore module version numbers altogether and only use the distribution version number from the distribution filename (using the heuristics in CPAN::DistnameInfo). I didn't want to get into the headaches of doing eval's or heuristics to try to find out a module's version number. I don't install or trust the modules in any way, so Schwern's argument wouldn't apply. Therefore I would have happily considered a module such as Module::SafeVersion; even if it is accurate only 99% of the time, that's better than nothing (which is what I have now).
Re: Is Module::SafeVersion a Waste of Time?
by dragonchild (Archbishop) on Apr 25, 2006 at 01:20 UTC
    PAUSE apparently runs in a chroot jail, so the only folks likely to be bitten by a version string attack would be smoke testers.

    Sounds like smoke testers should be running their smoking in a chroot jail, too. Maybe chroot jails need to be easier to set up ...

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Is Module::SafeVersion a Waste of Time?
by BrowserUk (Pope) on Apr 25, 2006 at 10:23 UTC

    Your premise appears to be that loading the module in order to obtain it's $VERSION is inherently unsafe; and you are attempting to reimplement some subset of the perl parser in order to avoid that "risk"; but if your module library is compromised enough that the risk of loading the modules it contains is real, how are you going to cater for the risk that your module is the one that has been compromised?

    Further, what is the point in determining a module's $VERSION safely, when to use that module, you will need to load it? At which point it's version would be available to you, but you would of course have exposed yourself to the risk of it's being evaluated.

    The only useful, non-paranoia uses I can see for this, would be: a) scanning the entire installed library and obtaining the versions of all the modules without ending up with them all loaded in your process; or b) risking 'collisions' between modules by loading them all simultaneously; but that would more easily be done by spawning one-liners that load the modules and print their $VERSION thereby isolating each from the next.

    my @allmodules = map{ ... } @INC; ... for my $module ( @allmodules ) { print "$module :", `perl -M$module le"\$${module}::VERSION"`; }

    I agree with Schwern.

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Is Module::SafeVersion a Waste of Time?
by demerphq (Chancellor) on Apr 25, 2006 at 09:07 UTC

    Linking revision data into version is extremely common, and very convenient practice. Id say you should support such versions.


      I do have a fair amount of code in place to allow them since it's so common. Unfortunately, as you can see from the examples above, trying to reliably parse such information is extremely difficult and in many cases, it's not worth the trouble. Hence my thoughts on special casing some modules. It's the only way I can do that reliably.


      New address of my CGI Course.

        Heres one I use regularly:

        ($VERSION) = sprintf "%d.%03d", 0, ' $Revision:: 6 $' =~ /::\s+(\S+)/; + #

        Im not convinced that there is a security issue here to be honest. I think im with Schwern on this. If there is a security issue with version evaluation you already have serious problems. I mean presumably they could have just set up the to nuke your system.....


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://545374]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (8)
As of 2018-04-27 00:16 GMT
Find Nodes?
    Voting Booth?