C stringsþÝ«ÌΉŠ‹ÿ
-
Great talk from the chaos communications congress 2014
http://media.ccc.de/browse/congress/2014/31c3_-6243-en-saal_1-201412292200-the_perl_jam_exploiting_a_20_year-old_vulnerability-_netanel_rubin.html#video
Personally I love it for the colorful language but otherwise it's hilarious how easily people can get screwed over by Perl's syntax "features".
-
Abstract, please?
-
tl;dr
lists in Perl have really funky behavior
the method of accessing arrays vs scalars and lists makes little sense
http://puu.sh/e7s1z/698acea5f0.jpglists expand funny
http://puu.sh/e7stn/75cff2ea27.jpg
lists can expand to function arguments
http://puu.sh/e7sAj/1238e72209.jpgthe cgi module in Perl creates a list from duplicate keys without you asking it to!
http://puu.sh/e7sd7/ac3c543341.jpgcgi module has a joke in the documentation
http://puu.sh/e7skR/69d9f81b14.jpgBasically in the end, he could exploit bugzilla on user creation because he could craft HTTP parameters to create a list when there could have been only a single arg. The list gets merged with another list in the fun way when creating the user. He could then populate any field with anything. i.e. make himself admin.
The second to last thing is exploiting the lsit to argument conversion. Apparently a super common pattern which he found on github searches is for people to do db->quote( cgi->param(blah) ). Since lists expand to arguments, one could make the 2nd argument of quote as the number 2. 2 means "NUMBER" and instead of Perl verifying that it's an actual number, it returns the string as is.
-
Basically in the end, he could exploit bugzilla
Glad there's a better bugtracker that doesn't have such problems...
Anyway, that's just silly, I agree.
-
I really enjoyed the guys in the QnA Segment trying to defend the stuff by saying "Derp, when learning Perl you learn to do things differently so you aren't affected" after the presentation showed that in fact people DID do things the exact way for the exploit to work.
-
...I'm having flashbacks... this was my life working on my perl bot when I started trying to do something object-oriented... "How do you ask for an array?" "You don't ask for not an array" 100% truefax
-
the cgi module in Perl can't handle params per spec
Which spec is that?
If you mean HTML, bzzt HTML 4.01 allows submitting multiple controls with the same name. In fact, HTML requires all successful controls in a form be submitted.
If you mean CGI, bzzt CGI 1.1 mentions nothing about what happens when QUERY_STRING has duplicates.
Meaning that this was left entirely up to the programming language as to what to do with duplicate controls.
Late Edit: As Zemm pointed out, select multiple boxes wouldn't work correctly if you couldn't pass multiple values for the same name, so it turns out that its implied that you must accept multiple form elements of the same name.
-
Which spec is that?
If you mean HTML, bzzt HTML 4.01 allows submitting multiple controls with the same name. In fact, HTML requires all successful controls in a form be submitted.
If you mean CGI, bzzt CGI 1.1 mentions nothing about what happens when QUERY_STRING has duplicates.
Meaning that this was left entirely up to the programming language as to what to do with duplicate controls.
Ah I got me. Really it's against conventional expectation rather than spec.
-
tl;dr
lists in Perl have really funky behavior
Not really. Whoever expected those results doesn't really know perl.
@delfinom said:the method of accessing arrays vs scalars and lists makes little sense
http://puu.sh/e7s1z/698acea5f0.jpg
[code]
$sclr = (1, 2, 'a', 'b', 'c');
[/code]
I'll admit I had to look at this one twice. That's not a list. If it were, the scalar value would be 5 (the length of the list). In this context, it's just a parenthesized expression. The comma operator evaluates is left argument (presumably for the side-effects of the evaluation), discards the result, evaluates its right argument, and returns that value. Thus, the result of(1, 2, 'a', 'b', 'c')
is'c'
.
[code]print scalar @list;[/code]
This one really demonstrates the author's lack of understanding of perl. The scalar value of a list is its length. Not only is 5 the correct answer, he's explicitly asking for that.
[code]%hash = (1, 2, 'a', 'b', 'c');
print $hash{'a'};[/code]
First, if youuse warnings;
which you always, always, always should, you get a warning that you are trying to initialize%hash
with an odd number of elements; that should be a clue that you're Doing It Wrong. Second, I'm at an almost complete loss as to why the author would expect$hash{'a'}
to beundef
. From later WTFs, though, it is apparent that he doesn't understand that=>
is just,
with a little syntactic sugar. (a => 'b'
is equivalent to'a' , 'b'
; it's just a list separator, but it implicitly quotes its left argument.) I can only guess that the author was expecting(1, 2, 'a', 'b', 'c')
to mean the same thing as(1 => undef, 2 => undef, 'a' => undef, 'b' => undef, 'c' => undef)
because he didn't use any=>
s, but (other than turning its left operand into a string), there's nothing special about=>
in a hash initializer; the values are still key/value pairs, regardless of which operator is used.
@delfinom said:lists expand funny
http://puu.sh/e7stn/75cff2ea27.jpg
'e' => @list
is exactly (because the'e'
is already explicitly quoted) equivalent to'e', @list
which is equivalent to'e', 'f', 'lol', 'wat'
. If he wanted the value of$hash{'e'}
to be a list, he needed to use'e' => \@list
. (Also, on every perl interpreter I've ever used,print $hash;
wouldn't produce either the expected or "reality" results shown, rather something likeHASH(0x10043fa0)
.print
doesn't natively handle data structures more complex than lists; you need to use something like Data::Dumper to get what the author expected.)lists can expand to function arguments
http://puu.sh/e7sAj/1238e72209.jpg
Arguments to a function are passed as a list. Again, lists (and hashes) in a list are always expanded. If you want to pass an actual list, you have to pass it by reference:\@list
.
-
reference:
\@list
Because the most logical way to say "I want a reference to this variable" is "the character that every language including this one uses for escaping newlines in string literals".
-
Because the most logical way to say "I want a reference to this variable" is "the character that every language including this one uses for escaping newlines in string literals".
At least it doesn’t use
&
for both referencing (as a unary operator) and bitwise and (as a binary operator), which is worse IMHO.
-
IIRC, Perl arrays collapse into lists of scalars if you so much as look at them funny. You need to use references if you want a complex data structure such as an array within an array, or even to pass an array into a sub without it collapsing into a list of scalars.
But this is all stuff you learn after a few hours writing Perl—I'm sure there's much much weirder stuff lurking within it than this. (Filehandles? Typeglobs? It's been a few years...)
-
I've officially been a perl programmer for just over 2 years now (did play with it c. 1998 but now it's really the only server side language I use at work) and miss a lot of these features when using other languages. Bringing lists together is a really handy feature.
If one RTFM then the expected and actual columns would match. Sometimes when using js or php those columns are swapped for me!
-
Not really. Whoever expected those results doesn't really know perl
Thanks for the run down.
I spotted a few of these, but it's been a while since I've touched perl. This reminds me of silly "proofs" that hide a divide by zero somewhere to show nonsensical results.
-
I'm sure there's much much weirder stuff lurking within it than this. (Filehandles? Typeglobs? It's been a few years...)
I've been trying to clean up and modernise some of our codebase. Things like map, // and ~~ can really save a lot of lines and unnecessary loops/conditionals. We don't even "use 5.10" for the most part!
-
But this is all stuff you learn after a few hours writing Perl—I'm sure there's much <i>much</i> weirder stuff lurking within it than this. (Filehandles? Typeglobs? It's been a few years...)
The argument by the presenter at the end is not that it's Perl's fault directly(it's designed that way) but it's the programmers fault but induced by Perl's shit. And because of that, he can basically search github for exploitable projects like a joke.
-
This post is deleted!
-
lists in Perl have really funky behavior
Just watched the video.
That guy is an idiot. I just did a little test in Javascript:
f = (1, 2, 'a', 'b', 'c')
Do you know what my console printed out? That's right.
"c"
He has lost all creditability now, since he said that every other languages would output 1.Regarding the CGI module: We recently upgraded it and it started issuing warnings that
$req->param
was called in list context, which I guess is addressing this "7 year old bug in Bugzilla". Fortunately (surprisingly?) our code was calling it in list context on purpose and was handling the case offoo=1&foo=2
by turning it into a hashref. (We use a few<select multiple>
boxes around the place).In the "List severly abused" section:
foo('a', @list, 'd')
feature is so useful and the best feature I miss in other languages!!! Declare a list and simply push stuff to it. Of course it is more useful infoo('a', %hash, paramX=>'d')
thensub foo { my $a = shift; my %param = @_; ... }
and presto: named parameters mixing optional and required/defaulting in the one declaration.And the DBI::quote "issue" is still calling cgi param in list context - same problem... We are safe! But not much of our code uses this anyway, it uses a lot of parametised queries.
He is still confusing lists and "arrays". What he wants is arrayrefs in many places!
Our code does have other problems which I'm not going into details (it's too horrible) but they would have been created in any language given the design of that part of the system!
(So horrible that when Bernard Pilsbury examined the residual shambles of the bungalow he said it was more gruesome than anything even he had ever seen. That from a great pathologist with unique experience constitutes a warning not to be ignored.)
-
-
-
Just watched the video.
That guy is an idiot. I just did a little test in Javascript:
f = (1, 2, 'a', 'b', 'c') ```</blockquote> I am thinking the confusion here is that Perl does two things (1,2,'a','b','c') can initialize an array and it can be an single line comma operator assignment. In JS and even C, that line is a valid functionality of the comma operator. But no way in hell could it ever be confused with or looks like initializing an array which uses curly brackets.
-
Shirley you mean ARRAYREF?
Oops!
And don't call me surely.
In JS and even C, that line is a valid functionality of the comma operator. But no way in hell could it ever be confused with or looks like initializing an array which uses curly brackets.
Square brackets? But yeah, perl is list driven but sometimes people forget that. There is a scalar keyword but no array or list equivalent because it will default to that context.
Don't worry, your creditability is intact.
Thanks. Even if you are being sarcastic it is now 1am and I should been in bed hours ago...
-
That video reminded me of https://www.destroyallsoftware.com/talks/wat
-
@delfinom said:
In JS and even C, that line is a valid functionality of the comma operator. But no way in hell could it ever be confused with or looks like initializing an array which uses curly brackets.
Square brackets? But yeah, perl is list driven but sometimes people forget that. There is a scalar keyword but no array or list equivalent because it will default to that context.
Woops, yes JS is square, C uses curly. Point is they don't repurpose the syntax to mean something else depending on location.
-
Point is they don't repurpose the syntax to mean something else depending on location.
Perl is the opposite of that. TMTOWTDI is the design principle behind the Perl 5 parser…
-
-
If one RTFM then the expected and actual columns would match.
A concise summary of my long-winded post! :)
-
As much as I (uninformedly) hate Perl, I do agree that most of the complaints are somewhat weak.
The core fault is the CGI function returning different types of objects depending on external unsafe input, with little to no indication that this can happen.
This would be idiotic in any dynamically-typed language (including python and friends).If this CGI function was written and used in python, repeated GET params would most likely just cause an exception (which can still result in vulnerabilities under some rare conditions, I'm sure), but perl seems to prefer arbitrary weirdness over exceptions, so the likelyhood of hitting vulnerabilities is much greater.
That's the reason Perl can indeed receive some of the blame for this. (Or at the very least, the practice of using Perl when security is a requirement)In statically-typed languages, by the way, a function that can return different kinds of data would be awkward to use (it would need to return a wrapper type, that callers would have to query to further determine what type of value they received).
This would suggest API designers to use the much more safe practice of requiring callers to specify the type of data you expect to receive (e.g. via generics or alternative functions)
-
@created_just_to_disl said:
In static languages, by the way, a function that can return different kinds of data would be awkward to use
...until you invent QVariant.
-
..until you invent QVariant.
Wow - that's horrible. They're trying to emulate a (very limited) dynamic type in a static language.
That is a more extreme example of what I thought a staticly-typed CGI->param could do, and it is awkward to use, but at the very least it requires the caller to specify which type they want explicitly. Any exceptions such a scheme would throw would happen immediately, which might be somewhat more secure than even the python variant - where they'll only be likely thrown on a subsequent usage.
I'm hoping that rather than use a scheme like QVariant, API designers in static languages would gravitate towards multiple functions and/or generics, but that does seem to be overly optimistic.
-
It probably should have been split up.
Its been a while since I've used PHP, but as I recall,
$_GET['blah']
will also be either a single value or an array based on the inputs, but they add the extra wtf that they are only combined into an array if they contain square brackets in their name (which potentially breaks the HTML spec).And yes, some other languages do this correctly, such as Java's getParameter for getting a single value and getParameterValues for multiple values.
Granted, if you're manually dealing with Servlet objects in Java...
-
@created_just_to_disl said:
If this CGI function was written and used in python, repeated GET params would most likely just cause an exception (which can still result in vulnerabilities under some rare conditions, I'm sure), but perl seems to prefer arbitrary weirdness over exceptions, so the likelyhood of hitting vulnerabilities is much greater.
If the submitted form data contains more than one field with the same name, the object retrieved by `form[key]` is not a **`FieldStorage`** or **`MiniFieldStorage`** instance but a list of such instances.
In fairness, Python web frameworks like Django get it right: https://docs.djangoproject.com/en/1.7/ref/request-response/#querydict-objects (only a single value is returned by default, and there is a special method to retrieve multiple values)
-
@created_just_to_disl said:
If this CGI function was written and used in python, repeated GET params would most likely just cause an exception (which can still result in vulnerabilities under some rare conditions, I'm sure)
Does "rare conditions" cover "attackers being able to bring down the server with a single malformed URI"?
-
Does "rare conditions" cover "attackers being able to bring down the server with a single malformed URI"?
Wouldn't most/all/more-than-all web frameworks prevent an exception when processing one web request from bringing down the entire server?
I think the web would be mostly down by now otherwise.The rare conditions I was talking about is mostly stuff like the exception leaving some shared object in a partial state.
-
QVariant
Or boost::any?
Although being able to use that kind of functionality without getting boost on you is probably desirable in its own right...
-
@created_just_to_disl said:
The rare conditions I was talking about is mostly stuff like the exception leaving some shared object in a partial state.
Oh well, I'm sure that's probably fine then...
-
That's not a list.
To be pedantic, the Perl documentation refers to "list" as the syntax, and "array" as the data type. The list syntax does not implicitly create an array, which is why you can't get it's length.
-
I don't know if anyone else has noticed/agrees with this, but it seems to me that PowerShell has quite a lot of Perl infuence in its design. It'd be interesting to compare some Perl/.NET code with a PowerShell doing the same thing...
-
...... vunderbar.
-
QVariant? boost::any? void* is just as good and is cheaper to integrate to existing codebase.
-
-
and my father's father before him
Tried to google it because I'm sure I heard this phrase before, but all I've found is religious bullshit and excerpts from religious books which don't contain this exact phrase at all.
-
i think it's either Jedi or Randall Munroe
-
Tried to google it because I'm sure I heard this phrase before, but all I've found is religious bullshit and excerpts from religious books which don't contain this exact phrase at all.
http://youtu.be/pjD8RhrgXDM?t=1m14s
(start at 1m14 if the link discourses up)
-
-
Until you hose up the memory management -- something like a QVariant tucks all that logic away under the covers in a reasonably encapsulated way.
-
It worked for my father, and my father's father before him.
Right up until someone forgot the type represented, right?
I'm (a little) surprised nobody mentioned these before. I bet they predate QVariants.
-
Until you hose up the memory management -- something like a QVariant tucks all that logic away under the covers in a reasonably encapsulated way.
Since you replied to me in a reasonable way pointing out why my proposal is inferior to the others, I hereby nominate you for WHOOOOOOOOOOOSH.
-
Since you replied to me in a reasonable way pointing out why my proposal is inferior to the others, I hereby nominate you for WHOOOOOOOOOOOSH.
Don't forget the
-
But seriously. Why would anyone want dynamic types in a statically typed language? That kills the whole purpose of having compile-time type checks.