Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Safe::Logs - Feedback appreciated

by fokat (Deacon)
on Mar 03, 2003 at 17:09 UTC ( #240075=perlmeditation: print w/ replies, xml ) Need Help??

Fellow monks:

A few days ago I came accross this article that exposes certain (and frightening!) vulnerabilities in some very popular terminal emulators. By the way, OS X's Terminal.app is also vulnerable to some of them.

Since we have a huge load of Perl code at our shop that sends info to the logs, it inmediately struck me: We were at risk, so I got busy. A few hours ago I uploaded Safe::Logs. What this module does is override warn(), die(), warnings::warn(), warnings::warnif() and Carp so that embedded ESC characters are replaced by a harmless placeholder, rendering the published attack ineffective.

The rationale for this was to require the smallest, safest modification possible to production code, so that applications could be patched fast. However, I would like the feedback from you so that I can incorporate the good ideas you might point out.

Best regards

-lem, but some call me fokat

Comment on Safe::Logs - Feedback appreciated
Re: Safe::Logs - Feedback appreciated
by theorbtwo (Prior) on Mar 03, 2003 at 18:17 UTC

    It's good, but it isn't enough. You stated you've got a lot of perl that writes to logfiles. Is it the only thing writing to those log files, and /are you /really/ sure/? (Yes, that was double-italics.) You need to filter any potentialy untrusted data before it gets to your terminal. That could be as simple as using less out of "raw" mode (assuming it doesn't have bugs of it's own), or piping it through tr/\e/<esc>/;, etc, etc.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

      (...) but it isn't enough.

      We both agree here. Perl is not our only producer of log files. I am aware of the possible workarounds, that in my case also implies performing substitutions in the logs as they are compressed and rotated as well as education for the fellow sysadmins.

      I believe a complete answer to this problem requires a set of coordinated actions at different levels, that include fixing the terminal emulators themselves. However, it wouldn't be appropiate to bring such extraneous non-Perl thoughts to this sacred monastery ;-)

      Thanks (and ++) for your valuable opinion, which happened to remind me of a patch I need to produce :-)

      Best regards

      -lem, but some call me fokat

Re: Safe::Logs - Feedback appreciated
by demerphq (Chancellor) on Mar 03, 2003 at 21:01 UTC

    I have to admit that I'm too busy right now to review your code, but you asked that I reply here to a couple of points from your other thread.

    I had to do something like what you describe for a log module I wrote, (although kind of the opposite as you will see). The objective was to retrofit a bunch of existing poorly looged scripts. My idea was to write a module that would allow a simple added use line to cause all activity on STDERR and STDOUT to get redirected to a log file. My approach was to tie STDOUT and STDERR, as well as add traps to $SIG{__WARN__} and $SIG{__DIE__}. (In hindsight overriding CORE::GLOBAL::die() and CORE::GLOBAL::warn() might have been better, but this catches errors from Perl itself, which can be useful.)

    This way virtually all output activity is intercepted, regardless if a module is the one that used the logger or not. In fact it probably is simpler than your approach as things like warnings::warn() actually use Carp which in turn use CORE::warn, which is in turn intercepted by the $SIG{__WARN__} handler, likewise for die().

    Generally speaking it works well, problems however occur when programs use sneaky ways to get access to the standard filehandles, and when other code installs $SIG{__FOO__} handlers and doesnt behave nicely. The latter is rare, but difficult to deal with as there isnt really a stated "nice" behaviour. For me its been rare enough that it hasnt been an issue. I still wonder when itll bite me though. :-)

    Anyway, I still think that arguably the best thing to do in your situation, is write a logfile reader, or a sanitizer of some sort. This is the only real way to address the fact that it will be almost impossible to intercept all writes to the log files in question wheras it is probably feasable to ensure that the files are not read without a tool. But thats not for me to decide is it? :-)

    ---
    demerphq


      Anyway, I still think that arguably the best thing to do in your situation, is write a logfile reader, or a sanitizer of some sort. This is the only real way to address the fact that it will be almost impossible to intercept all writes to the log files in question wheras it is probably feasable to ensure that the files are not read without a tool. But thats not for me to decide is it? :-)

      Well, actually I tried to send email to the maintainer of Logfile::Rotate to see if he would be interested in adding this features to the package. Unfortunately the email bounced...

      I agree with your point. However, teaching old-dogs new-tricks is not easy. Many people use tail -f or similar, so building and deploying a log-reader will take some time. I thought this would be a quick solution for, say, 70% of the problem in our case.

      Again, thanks a lot for your comments.

      Best regards

      -lem, but some call me fokat

        Well, actually I tried to send email to the maintainer of Logfile::Rotate to see if he would be interested in adding this features to the package. Unfortunately the email bounced...

        Did you try his CPAN address? That's different from the one in the module.

        Hugo

        This actually raises what is to me an interesting question. What to do when your work uses an open source module whose author is either not able or willing to make the modifications you would like, or disappears completely so cannot make any patches at all?

        Here we have branched a couple of modules where the authors were unresponsive or dismissive of our changes. So now we use a custom version of MIME::Lite and Config::Inifile the former because Eryq doesnt answer mails and hasn't updated the module (despite posted bugfixes) in two years, and the latter because despite providing patches the authors decided they didn't want the functionality we needed. This means that for these modules we use our own distributions, which is annoying but better than doing a complete rewrite to utilize a supported module.

        After conversations with a number of Open Source types lately Ive been seriously thinking about hijacking MIME::Lite until the author returns to Perldom. In fact we were contemplating a "CPAN Orphanage", perhaps a sourceforge project for all the CPAN modules whose authors have abandonded them.

        So I guess the relevent point to you is that if you want a patched Logfile::Rotate and you cant get the author to integrate the change, then fork it and use your local copy anyway. If the author isn't maintaining the module anyway I dont see any reason not to.

        ---
        demerphq


Re: Safe::Logs - Feedback appreciated
by Zaxo (Archbishop) on Mar 03, 2003 at 22:42 UTC

    This comment has nothing to do with protecting broken terms (replace 'em!).

    It's rare and may be difficult to test, so it's a common vulnerability. What happens if the logging device fills up? On a machine with /dev/full (Linux and a few others may have it), you can say:

    { open local(*LOG), '>>', '/dev/full' or die $!; # run tests }
    That will cause prints to LOG in the test code to fail on flush with $! = ENOSPC. That may happen either in the print, or on closing the handle.

    As always, ignoring errors on system calls can lead to Bad Things.

    Update: ++premchai21 for catching an embarassing typo that turned /dev/full into the useless-for-this /dev/null. Easy to see where that came from!.

    Here's an example of the kind of thing to watch for. STDERR is reopened to be a dupe of the LOG handle: print LOG $@ or die $!; # d'oh!

    After Compline,
    Zaxo

      What happens if the logging device fills up?

      I was under the impression that most modern systems had limits on the max sizes of the logfiles and that the logging mechanism would automagically rotate the logs as necessary. It certainly ought to be that way.

      OTOH, before I started using Linux I was also under the impression that modern systems would automagically use available drive space to create swap space as needed...


      for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc' .'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$ p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://240075]
Front-paged by TStanley
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2014-12-28 06:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (178 votes), past polls