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.jpg

    lists expand funny
    http://puu.sh/e7stn/75cff2ea27.jpg
    lists can expand to function arguments
    http://puu.sh/e7sAj/1238e72209.jpg

    the cgi module in Perl creates a list from duplicate keys without you asking it to!
    http://puu.sh/e7sd7/ac3c543341.jpg

    cgi module has a joke in the documentation
    http://puu.sh/e7skR/69d9f81b14.jpg

    Basically 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.



  • @delfinom said:

    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.


  • Winner of the 2016 Presidential Election

    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.

    Filed Under: So, what language is worse, PHP or Perl? :trollface: (I know that thread is somewhere around here. I am just too lazy to look it up again)


  • I survived the hour long Uno hand

    ...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



  • @delfinom said:

    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.



  • @powerlord said:

    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.



  • @delfinom said:

    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 you use 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 be undef. 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 like HASH(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.)

    @delfinom said:

    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.



  • @HardwareGeek said:

    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".



  • @ben_lubar said:

    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!


  • ♿ (Parody)

    @HardwareGeek said:

    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.



  • @tar said:

    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!



  • @tar said:

    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!


  • @delfinom said:

    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 of foo=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 in foo('a', %hash, paramX=>'d') then sub 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.)



  • @Zemm said:

    He has lost all creditability now

    Don't worry, your creditability is intact. ;)



  • @Zemm said:

    handling the case of foo=1&foo=2 by turning it into a hashref

    Shirley you mean ARRAYREF?



  • @Zemm said:

    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.


  • @OffByOne said:

    Shirley you mean ARRAYREF?

    Oops!

    And don't call me surely.

    @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.

    @Keith said:

    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...


  • Winner of the 2016 Presidential Election



  • @Zemm said:

    @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.


  • Discourse touched me in a no-no place

    @delfinom said:

    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…


  • FoxDev

    @dkf said:

    . TINCWTDI

    FTFY



  • @Zemm said:

    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.



  • @flabdablet said:

    ..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"?



  • @tar said:

    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.



  • @flabdablet said:

    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...



  • @HardwareGeek said:

    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...


  • FoxDev

    ...... vunderbar.


  • Banned

    QVariant? boost::any? void* is just as good and is cheaper to integrate to existing codebase.



  • @Gaska said:

    void*

    It worked for my father, and my father's father before him.


  • Banned

    @tar said:

    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.


  • FoxDev

    i think it's either Jedi or Randall Munroe


  • Discourse touched me in a no-no place

    @Gaska said:

    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.

    Lynyrd Skynyrd - Can't Take That Away – [01:14..04:25] 04:25
    — marking96


    (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.


  • Discourse touched me in a no-no place

    @tar said:

    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.


  • Banned

    @tarunik said:

    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.



  • @Gaska said:

    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 🚩


  • Banned

    But seriously. Why would anyone want dynamic types in a statically typed language? That kills the whole purpose of having compile-time type checks.


Log in to reply