-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
magic open of ARGV #1566
Comments
From thospel@mail.dma.beIn article <E12V7Jw-0002PL-00@ursa.cus.cam.ac.uk>,
In fact, there was a little known third proposal by yours truly (hi !): mkdir /tmp/a Will also give you the dreaded: So, since a security aware person has to do perl -wne '' -- * anyways, let that remove the magicness |
From @smpeters
The flow Ton has just above seems to have been fixed. steve@kirk:~/perl-current$ mkdir /tmp/a Although the original flow that started this ticket still exists. |
From perl5-porters@ton.iguana.beIn article <rt-3.0.11-2783-121717.9.08824524474802@perl.org>,
Just downloaded and tried a bleadperl. Still works for me. perl -wne '' '-e;print("Bwahaha\n")' which is *supposed* to work. Maybe it's your shell that refuses to expand the file with an option |
From prev a.r.ferreira@gmail.comOn 9/28/05, Ton Hospel <perl5-porters@ton.iguana.be> wrote:
If I am not overlooking some point in the current discussion, the If you want to use "<ARGV>" processing in a totally boring and non-mag- # "Sam sat on the ground and put his head in his hands. So if you don't trust your script users, your code must be more robust About the possibility to introduce an extra (potentially malicious)
and files with weird name like '-e;print("Bwahaha\n")', this won't
would get the -e as an argument. So don't use one-liners with Maybe the documentation could include one or two phrases on the |
From @tamiasOn Thu, Sep 29, 2005 at 09:02:27AM -0300, Adriano Ferreira wrote:
Putting -- before the argument list should avoid that problem. perl -wne '' -- * Ronald |
From @pjfRaising this bug from the dead so we can lay it to rest at last. The original bug report reads:
Yes, <> using 2-argument open just contain a nasty surprise. I don't myprog.pl log.0 log.1 'gunzip -c log.2.gz |' and have <> work its magic. This means I don't think we'll see <> changing to using 3-argument open Luckily, there's a reasonably good work-around, and that's to use taint If the program didn't intend to execute external commands to begin with, One can still potentially use the arcane invocation '<&=0' to dup STDIN As such, I'm resolving this ticket and marking it as not-a-bug. Cheerio, Paul -- |
@pjf - Status changed from 'open' to 'rejected' |
From @jbenjoreOn Wed, Jul 2, 2008 at 12:33 AM, Paul Fenwick via RT
I'm of the opinion that working code should break in new versions of I find it incredibly aggravating that my one-liners do the wrong thing
No.
No. Josh |
From @ysthOn Mon, July 14, 2008 3:55 pm, Joshua ben Jore wrote:
No.
I'd be fine with breaking the feature in 5.12 by default, but Note that changing from 2-arg to 3-arg open breaks the following idiom @ARGV = <>; because trailing newlines on the filenames are no longer ignored. |
From @ap* Yitzchak Scott-Thoennes <sthoenna@efn.org> [2008-07-15 03:10]:
Writing chomp(@ARGV = <>); is no great hardship. (Note that at this time I am not taking either side in the -- |
From ben@morrow.me.ukQuoth twists@gmail.com ("Joshua ben Jore"):
How about making the implicit open done by <> use either main::open (if to open my $FH, '<', '<foo'; ? Ben -- |
From @jbenjoreOn Tue, Jul 15, 2008 at 6:10 AM, Ben Morrow <ben@morrow.me.uk> wrote:
Ok, but name it UnsafeOpen.pm because the default should work Josh |
From @epaJoshua ben Jore <twists <at> gmail.com> writes:
FWIW, I completely agree with this. In my opinion it is much, much too Yes, taint mode does prevent this, but unless taint mode is on by default for Perl's motto is that easy things should be easy: surely reading some files Please could I ask the perl5 core team to have another look at this bug report. -- |
From tchrist@perl.com
It's not obvious where in your text you've made the transition
People who create files with aggravating names are aggravating people; chdir "/tmp"; Then there's the protection measure of "touch ./-i"; think about it. If it takes a syswide find to locate unpleasant filenames and send And the day that I can no longer rely upon the overlying system to What you don't seem to understand is that taking a homogeneous approach to When you make every program encode the logic of treating "-" as special, Those ignorant of Unix are doomed to reinvent it--poorly. Don't go there. *DON'T!* You would ask this sort of idiocy: % perl -le 'open(IT, ">", "-")||die; print IT "stuff"; close(IT)||die' Just say no. I could put it more strongly, but if you haven't figured out
Not merely wrong, but exceptionally so. --tom |
From mark@mark.mielke.ccTom Christiansen wrote:
That open(handle, arg) doesn't translate 1:1 as a system call open() I often find myself wishing Perl accepted many MORE magical open perl -pe 1 http://www.cpan.org/index.html For applications with security concerns, the argument to open() still Cheers, -- |
From @arcTom Christiansen writes:
And yet, in the context of Unix as a whole, every program _already My strong suspicion is that a large part of what to consider correct I'm certainly not suggesting that Perl's long-standing behaviour here I also note that some of the most interesting uses of magical perl -lne '...' 'command1 | filter1 |' 'command2 | filter2 |' -- can in modern shells be handled with process substitution: perl -lne '...' <(command1 | filter1) <(command2 | filter2) I'm not convinced that that really constitutes an argument one way or -- |
From zefram@fysh.orgAaron Crane wrote:
I think this convention is obsolete. If you want to refer to standard -zefram |
From @arcZefram writes:
True, but it's a lot more work to type. Also, it doesn't behave quite the same way on all operating systems. $ uname $ tail -c +52 /usr/share/dict/words | head -1 $ perl -w stdin.pl - < /usr/share/dict/words On some OSes (including BSD), opening /dev/stdin is equivalent to Linux differs; opening /dev/stdin gives you a file descriptor open on As it happens, Perl's magical open of "-" is neither dup(0) nor -- |
From @epaTom Christiansen <tchrist <at> perl.com> writes:
You seem to have in mind the comfortable Unix environment most of us remember You can't run a system-wide check for 'unpleasant' filenames before every Remember that here we're not talking about some obscure construct that only But security holes are just one specific class of bugs. In principle, the issue
If I might go rhetorical for a moment: to rely upon the overlying system? That So why doesn't the C library automatically treat '-' as stdin or stdout?
Absolutely. It would be crazy for perl or any other program to start doing % cat <(echo hello; echo goodbye) and cat, and every other program, had to have special code to recognize '<' in
That's exactly the behaviour I see with perl 5.10. What result do you get? -- |
From @epaMark Mielke <mark <at> mark.mielke.cc> writes:
The issue here is that while (<>) { ... } is using the magical 2-argument open, with all the implications of running The un-magic alternative requires a lot more code. Surely this is backwards: As I see it, then, the choices are - Change while (<>) and while (<ARGV>) to use 3-argument open, perhaps with - Or change every Perl tutorial starting with Perl's own documentation to note - Or introduce a new language construct 'the safe way to read command line -- |
From @AbigailOn Fri, Jul 25, 2008 at 03:13:02PM +0000, Ed Avis wrote:
What does the current directory have to do with while (<>)? while (<>) reads from filenames from @ARGV, not from the current directory.
- Teach people not to use "funny" characters in the filenames lightly, Abigail |
From @AbigailOn Fri, Jul 25, 2008 at 03:05:30PM +0000, Ed Avis wrote:
Oh, come on. This is a solved problem. The answer is -T: $ perl -wTE 'while (<>) {print}' '> foo' -T is recommended both for CGI programs, and programs running as root. Abigail |
From @AbigailOn Fri, Jul 25, 2008 at 04:36:56PM +0100, Ed Avis wrote:
If you are running "my_program *" as root in a directory where black hat people For instance, 'rm -i *' won't ask for each file whether it should be deleted The answer here is to teach people to not blindly assume their insecure Abigail |
From @epa
That deals with a lot of it, but the -T flag is not the default. By default if you write the innocuous-looking perl program use warnings; you will get a program with all the magical, dangerous behaviour discussed earlier in this thread. It would be better if safety were the default, with some special command line flag or 'use' to turn on the unsafe behaviour. To get some real-world data: if you pick the first page of results from I suppose that 'use warnings' could print out a warning on 'while (<>)' saying 'this construct is not safe unless you use -T', but that seems daft to me. Just make it safe to use, no ifs and no buts. Even with -T, the program will abort when the '>foo' filename is found, which is not great for something that's purportedly meant to just read some files. The issue is not that expert programmers should be able to turn on some particular flag or use some particular incantation to read files given on the command line in a safe way. The issue is that the simple, small, innocuous-looking code is dangerous. IMHO, the simple code 'while (<>)' should be safe for all uses, and the flags, bells and whistles can be added to turn on the magical, risky behaviour if wanted. -- ______________________________________________________________________ |
From @epaAbigail asked:
Sorry, I was thinking of the common usage of % my_program *
I agree that using funny characters deliberately is not a good idea. However, they do sometimes appear by accident, and they can be made to appear by anyone who has write access to the directory where 'my_program *' is run. If my_program uses 'while (<>)', then if 'my_program *' is run by root in a certain directory, you are effectively granting root command access to anyone who can create a file in that directory. Even in less drastic cases than the above (which is the worst case, but certainly not impossible) a similar bug can be used as part of a multi-step exploit; perhaps the web server has a bug that means an attacker can cause it to write a zero-length file in a certain logfile directory; then a log grepper script might get caught. Again this is just an example. Even if there are no security implications because only one person uses the computer and there are no external-facing daemons to be compromised, it is still a peculiar behaviour for the program to go off and try to run the command 'x' when the filename '>x' was given on its command line. No standard Unix utility does this: % grep hello '>x' although many standard Unix programs take an argument of '-' to mean read from standard input, which is not usually dangerous. -- ______________________________________________________________________ |
From @epaAbigail wrote:
That is true. But I wouldn't expect 'grep *' to go off running random external programs. Not even if grep were implemented in perl.
That is a good thing to teach, and the first lesson would be 'do not use while (<>) unless you also use -T'. However that is not mentioned in any perl tutorial I know of. If you have a tool which is potentially dangerous, one alternative to giving this kind of warning is to provide beginners with a safer (if somewhat blunter) tool for everyday use. They can graduate to the more dangerous one when they are ready for it, and understand the risks. That's why I think that 'while (<>)' would better be the safe kind of 'read all the files', and the more dangerous kind should have a syntax that marks it as such and cautions you not to blindly assume it will be safe. -- ______________________________________________________________________ |
From @davidnicolOn Fri, Jul 25, 2008 at 11:14 AM, Ed Avis <eda@waniasset.com> wrote:
perhaps, 'while(<<>>)' could be the current 2-arg semantics from 5.11 -- |
From @AbigailOn Fri, Jul 25, 2008 at 02:39:16PM -0500, David Nicol wrote:
So, you are willing to break programs that currently use the fact <> The problem here Ed is painting here isn't 2-arg open; it's people not (You know, not all Perl tutorials rewrote themselves the moment 3-arg Now, the idea of having both '<>' and '<<>>', and have one of them do 2-arg Abigail |
From perl@nevcal.comOn approximately 7/25/2008 12:53 PM, came the following characters from
One could speculate about "while(<>)" using 2-arg open if -T is set and But to answer your question, yes. How else can we encourage the dimwits to continue using perl, after they So open docs do say:
But there is no warning of all that under control flow statements in I've long since learned not to use certain characters in filenames, and I, myself, have had to agree to use Python for a current project, --
|
From @moritzAbigail wrote:
I think they don't conflict: patch the docs for 5.8.9 and 5.10.1, and The problem with informing the people out there is that you don't reach Hell, if they know about basic use of <> already they won't read the (I programmed in perl for about 3 or 4 years before having any contact Moritz |
From @AbigailOn Tue, Jul 29, 2008 at 11:52:01AM +0100, Ed Avis wrote:
I think we are misunderstanding each other. And now I no longer know what Abigail |
From @epaI thought you were suggesting something like use feature 'diamond_is_safe'; if the existing default behaviour of <> is kept, or use feature 'diamond_is_magic'; if <> is changed to be safe by default. 'use'ing either of these features would prevent the code running on older perls. I asked, is it possible for a CPAN module to provide a 'feature' for older perl versions? So that if the module is installed, 'use feature X' loads the module and turns on that feature, even though perl doesn't have it builtin? -- ______________________________________________________________________ |
From @davidnicolWhoever is compiling the module of handy preprocesses for ARGV may BEGIN { @ARGV = map "< \Q$_\E" @ARGV } as in cat <<EOM > SafeMagicalFootball.pm sub import { @ARGV = map "<\Q$_\E" @ARGV } 1; |
From hashin_p@thbs.comWhat do \Q and \E stand for? On Tue, Jul 29, 2008 at 2:22 PM, Mark Mielke <mark@mark.mielke.cc> wrote:
|
From @davidnicolOn Tue, Jul 29, 2008 at 8:22 AM, Mark Mielke <mark@mark.mielke.cc> wrote:
phooey. Prefixing < takes care of opening and reading files with pipes and so -- |
From @AbigailOn Tue, Jul 29, 2008 at 09:20:28AM -0500, David Nicol wrote:
It has been documented for a long, long time how to solve this: my $file = " hello "; Granted, "\0" is a bit of an oddity, but it is possibly. And you don't I think the current documentation is in perlopentut. Abigail |
From @davidnicolOn Tue, Jul 29, 2008 at 9:32 AM, Abigail <abigail@abigail.be> wrote:
so would $_ = (m|^/| ? "< $_\0" : "< ./$_\0") for @ARGV; work as a football safety device, inserted into the execution process |
From @apHi Tom, * Tom Christiansen <tchrist@perl.com> [2008-07-29 05:40]:
do these scripts enable warnings? * Abigail <abigail@abigail.be> [2008-07-28 21:30]:
Exactly. I want to highlight this again: in my opinion, having We can discourage the unconsidered use of magic ARGV with a Regards, |
From tchrist@perl.comIn-Reply-To: Message from Mark Mielke <mark@mark.mielke.cc>
"Obvious", you say. And obvious I suppose it is--to me and thee. But I'm increasingly susiciousness that we two may *not* be common case- Well, to me. What instead seems obvious is people without competence in security If you don't understand fundamental matters of security but are Perl arose in a culture where the security exploits most of us were worried Perl's dataflow-tracing that's engaged in taint mode was a real innovation That "*can*" is a big one. Just because it can, doesn't mean it does. I once ran a code-review for company that did online Perl training. As part Incredible, you may say, but perfectly and terrifyingly true. More than once upon showing users the rename/relink/pathedit $op = shift; Why were they screaming? Because of the eval. They say, but now % rename 'system("/bin/rm -rf / &")' *.c or some similar mayhem. I then ask them how likely it is that they are ever going % /bin/rm -rf / into their own shells, and of course they say, "Never, that would But as you see, there's a misconnect here, because it's no different. If you are the author of the code that you're running, you can trust If you are not that code's author, merely its executor, then you If you write code that's run by untrustworthy agents, If you run code that was written by untrustworthy agents, To my mind, it's a bug that while(<>) in taint mode doesn't % perl -ne 'print ; exit' /etc/passwd % perl -Tne 'print ; exit' /etc/passwd Since it knows that that's tainted data: % perl -MDevel::Peek -E '$s = shift; say Dump($s)' /etc/passwd % perl -MDevel::Peek -TE '$s = shift; say Dump($s)' /etc/passwd And knows better than to let you use it in external commands: % perl -MDevel::Peek -TE '$ENV{PATH} = "/bin:/usr/bin"; $s = shift; print Dump($s); system("head", -1, $s)' /etc/passwd --tom |
From @rgs2008/7/29 Aristotle Pagaltzis <pagaltzis@gmx.de>:
If I parse you well, that's indeed a compelling argument. Finding a
Recapitulating what was proposed by you, we are getting to : |
From tchrist@perl.comIn-Reply-To: Message from Abigail <abigail@abigail.be>
It's amazing what people expect. If I've heard it once--and I have--then These aren't competent professionals. They're programming strumpets just
Because while you can lead a horse to water, but you can't make it drink. Which just shows that you can't win for trying. I spent years on it--YEARS. They still just won't learn. Things like this It used to be right there prominently in open in the perl 4.036 manpage: The filename that is passed to open will have $file =~ s#^(\s)#./$1#; But that is now hidden away at best. And it's no longer Certainly the 1997 version of perlfaq5 covered it. It once read: How can I open a file with a leading ">" or trailing blanks? Normally perl ignores trailing blanks in filenames, and interprets sub safe_filename { $fn = safe_filename("<<<something really wicked "); You could also use the sysopen function (see sysopen). What do we get today? Bowdlerization! How can I open a file with a leading ">" or trailing blanks? (contributed by Brian McCauley) The special two argument form of Perl's open() function ignores Unless you have a particular reason to use the two argument form you open FILE, "<", " file "; # filename is " file " HELLO? What happened to the right answer that was there before? But what should I expect? The perl faq is now a document that thinks # ... It's *terribly* misleading! Notice that while loop's close curly. Oh # ... There are entries like that throughout. Makes me want to Which brings me to my final complaint of the day. That code is Watch: % df -h . % ls -l it* % perl -i.orig -pe 'print "this is more stuff\n"' it % echo $? % ls -l it* To this day, Perl's implicit closing of files doesn't warn you of errors, I've never convinced anybody this is important. Since *every* END { close(STDOUT) || die "can't close stdout: $!" } But that sort of thing should happen on all implicitly closed things. And Watch again, starting from before the bogus, ill-reported rename attempt: % df -h . % ls -l it % perl -e 'print "stuff\n"' >> it; echo $? % perl -e 'open(my % echo $? % ls -l it This is all incorrect behavior on Perl's part. Even cat knows better! % echo foo | cat >> it; echo $? +-------------------------------------------------------+ What's that about, eh? But I've been saying this for years, just like everything else. BTW, this proves my point about checking for print's status % perl -e 'open(my And you can't get the danged thing to detect its folly: % perl -WE 'open(my I firmly believe that this needs to be a part of *EVERY* Perl program, END { close(STDOUT) || die "can't close stdout: $!" } And I believe this *much* more than some here believe <ARGV> needs to And no, Abigail, *please* understand that I don't mean *you* personally in 'Nuff of this: time for sunshine. --tom Quotes below are all from Dorothy Parker: "You can lead a whore to culture, but you can't make her think." "You can't teach an old dogma new tricks." "If you want to know what God thinks of money, just look at "All I need is room enough to lay a hat and a few friends." "Brevity is the soul of lingerie." "The cure for boredom is curiosity. There is no cure for curiosity." |
From tchrist@perl.com
As I myself tried to show, it depends on what you're doing. Apparently, there's some idea that merely opening a file I'm not 100% sure that's true. But building in -f tests etc --tom |
From @epaTom Christiansen <tchrist <at> perl.com> writes:
FWIW, I agree. Since currently <> uses unsafe open, taint should flag it. At But, again, this might prompt you to ask why just 'reading the files' should #!/usr/bin/perl -T It executes just fine, and that is entirely correct. The open() call is safe, Taint checking and safe, predictable I/O commands are orthogonal. If you have a -- |
From @ap* Rafael Garcia-Suarez <rgarciasuarez@gmail.com> [2008-07-29 22:45]:
I think you are. The argument in full length is: if someone And we know the legions of ancient perls that are still deployed, For that reason, changing the semantics of `while (<>)` is a bad
Apart from the warning, obviously, per the paragraph you quoted
Yes. I want to note that I’m not enamoured with the choice of `<<>>` Anyway, I *think* this approach satisfies everyone’s concerns. Regards, |
From @ap* Tom Christiansen <tchrist@perl.com> [2008-07-29 23:25]:
It absolutely is. I had no idea, and as far as I’m concerned it’s * Tom Christiansen <tchrist@perl.com> [2008-07-29 21:45]:
Yes. Regards, |
From tchrist@perl.comIn-Reply-To: Your message of "Wed, 30 Jul 2008 01:57:14 +0200."
Hello, Aristotle. I'm quite glad to hear you say that. Maybe one's grandparents are right, and all one has to do --tom |
From tchrist@perl.comIn-Reply-To: Message from Aristotle Pagaltzis <pagaltzis@gmx.de>
Indeed; nor am I.
I wouldn't hold my breath; but you never know. I do note how Larry seems never to have thought a warning merited I opine that it's always been the position that hostile-environment I don't mean real security problems are ever treated lightly. I just find it hard to see that this anymore than another of many
I'd like to think about it a bit more. I still have a vague hunch like a module, or here even a pragma, In any event, I don't think that the alarmicists' loudness should cause while (defined ($data = <FH>)) { ... } To quiet the very, very annoying warnings that came from the risk of It didn't really become too noticeable until Windows, which thought that So for a while, *EVERYBODY* had to change their programs. That alone while ($var = readXXX()) { ...} for XXX = {line,dir,link}, which was the *much* better solution, by far. There are plenty of similarities here to that situation. I'm afraid we may be heading down, if not break-their-programs, at ---tom FN: "0 but true" is exempt from numeric warnings, just like the very % perl -WE 'say "001"+"000"' % perl -WE 'say 1+"3 blind mice"' % perl -WE 'say 1+"0 but true"' % perl -WE 'say 1+""' % perl -WE 'say 1+(2==3)' Although: % perl -Mbignum -WE 'say "000"+"001"' And: % perl -WE 'say "Inf" + 0' vs % perl -Mbignum -WE 'say "Inf" + 0' |
From @rgs2008/7/30 Aristotle Pagaltzis <pagaltzis@gmx.de>:
I concur. A patch would help, but I know that PerlIO is not the simplest A proper bug report would help, too, because currently this one is deep |
From @epaRoland Giersig <rgiersig <at> cpan.org> writes:
Either have a warning or change the semantics; I don't think you need both.
Pragmas are useful when you want to change the global behaviour of a program. So I think a pragma is overkill here, better a way to explicitly say what you
I think this is also getting a bit hairy and tangled.
Um, I don't know, after all one of the main points is that people were and are Let's not put extra bizarre stuff into 'use 5.xx', it is awkward enough already. -- |
From @AbigailOn Wed, Jul 30, 2008 at 02:49:51PM +0200, Roland Giersig wrote:
[ Proposal to change the meaning of <> ]
Eh, the argument Aristotle and I used, and Rafael agrees with isn't that Surely you must agree that a program is safer if it refuses to run on a Abigail |
From zefram@fysh.orgTom Christiansen wrote:
I don't see Bowdlerisation here. I see a better way to achieve the
It was superseded by this simpler right answer, when the three-argument
I agree with your problems with this one, however.
I wholeheartedly agree with you in this gripe. I often (but, admittedly, sub IO::Handle::safe_print { shift->print(@_) or die $! } and I wish such dying versions of I/O functions were standardised and -zefram |
From @AbigailOn Wed, Jul 30, 2008 at 05:01:38PM +0200, Roland Giersig wrote:
The case discussed here is not smart programmers. If we had programmers And as long as we have dumb programmers who should need protection, Abigail |
From @davidnicolOn Tue, Jul 29, 2008 at 6:30 PM, Aristotle Pagaltzis <pagaltzis@gmx.de> wrote:
As the overcaffeinated fool who suggested that operator, in the ensuing anyway after learning of the possibility of altering the filenames as |
From rick@bort.caOn Jul 30 2008, Aristotle Pagaltzis wrote:
Please submit a (more descriptive) bug report if you are serious. I, -- |
From @sciuriusEd Avis <eda@waniasset.com> writes:
Now that pragmas are lexcially scoped, this assumption no longer -- Johan |
From @sciuriusTom Christiansen <tchrist@perl.com> writes:
I'd go for a nice iterator class instead of <<<<>>>> weirdness. I don't mind typing a few more characters, especially since (as -- Johan |
Closed 🔐 |
Migrated from rt.perl.org#2783 (status was 'rejected')
Searchable as RT2783$
The text was updated successfully, but these errors were encountered: