Live data from Hacker News

Arbitrary file execution in TZinfo (Ruby)

github.com

11–20 of 30 posts

Re: Arbitrary file execution in TZinfo (Ruby)

#11
post #3
post #2

Does anyone know if this uses ICU under the covers? Is that affected too?

I don't believe that's the case, looking at the commit [0] [0] https://github.com/tzinfo/tzinfo/commit/01bcca5de920093b52fb...

Interesting. The reason for a bug seems to be that ^ and $ in regexps match a boundary of any line, not boundaries of a string. This have already caused problems in the past, as far as I remember, but Ruby developers didn't change the behaviour of these characters.

So if you write a regexp like /^[0-9]$/, a string "Any characters\n12345\nAny characters" will match the regexp.

Re: Arbitrary file execution in TZinfo (Ruby)

#12
post #5

Do any Ruby devs have an idea about how widely exploitable this vulnerability is? The GitHub issue mentions that a file upload could trigger this. I'm guessing that's because the time zone is included in the "date modified" field, but that's just a hunch. If anybody is able to quickly spin up a Ruby on Rails app with a file uploader, I bet somebody be happy to bang on it and see if they can get an exploit to trigger.…

Newer versions of tzinfo use non-ruby files for their data and are not effected afaict.

My guess is that it might be exploitable when parsing a user provided datetime with zone without any sanitization of the input. And only when using that get method. I might try to see if Rails is vunerable to this, but probably not from a cursory glance

Re: Arbitrary file execution in TZinfo (Ruby)

#13
post #5

Do any Ruby devs have an idea about how widely exploitable this vulnerability is? The GitHub issue mentions that a file upload could trigger this. I'm guessing that's because the time zone is included in the "date modified" field, but that's just a hunch. If anybody is able to quickly spin up a Ruby on Rails app with a file uploader, I bet somebody be happy to bang on it and see if they can get an exploit to trigger.…

> Do any Ruby devs have an idea about how widely exploitable this vulnerability is? The GitHub issue mentions that a file upload could trigger this.

The file upload itself is only part of the exploit.

If we assume the exploit as "executing code that is written by the attacker"¹, then the requirements are:

1. ability to upload an arbitrary file to a filesystem accessible by the host

2. ability, for the attacker, to pass values that are ultimately sent to `TZInfo::Timezone.get()`

With those conditions in place, the attacker will attempt to figure out where the file is located (with multiple attempts or so), then make `Timezone.get()` load the file.

It's not clear to me if `Timezone.get()` is indirectly invoked by some common Rails API, or if this is an API that is commonly invoked by the user.

As a starting point, one should check if they're invoking such API in their app.

EDIT: at a brief check, ActiveSupport exposes a `TimeZone` wrapper, that invokes `TZInfo::Timezone`, and can be used for the exploit.

EDIT2: It seems that the instatiation is not user-initiated (I suppose it's automatic... and not obvious to track), so unless the app devs intentionally perform this instantiation, I think they won't trigger custom calls (but I don't want to give false assurances).

EDIT3: I wonder if this can be triggered by putting certain data in the database and triggering loading. I can't exclude this vector because... Rails is complicated :). Seems overly complex, though. I think Rails intimate knowledge is necessary in order assess with very high certainty which the possible attack vectors are.

[¹] I'm making this distinction because if point 2 applies, but not point 1, the attacker can still execute arbitrary files preexisting in the filesystem.

Re: Arbitrary file execution in TZinfo (Ruby)

#14
post #8

Is it really a bug in tzinfo? I think the bug is in the app that pass in user input as time zone

It is a bug in tzinfo. It should not execute random files when given invalid timezone identifier. The app doesn't know what is a "valid" or "invalid" timezone, it is tzinfo's responsibility to check it. UPD: in fact tzinfo tried to validate a timezone identifier but did it the wrong way. It used a regular expression like /^...$/ and using ^ and $ is a mistake here. This allows to bypass validation by passing a multil…

Regex strikes again! I wonder how long it will take the computer industry to realise they just don't belong in code. Seems like most people still accept that they're hard to read and can't parse HTML but otherwise fine.

Re: Arbitrary file execution in TZinfo (Ruby)

#16
post #3

Earlier quoted context omitted.

I don't believe that's the case, looking at the commit [0] [0] https://github.com/tzinfo/tzinfo/commit/01bcca5de920093b52fb...

Interesting. The reason for a bug seems to be that ^ and $ in regexps match a boundary of any line, not boundaries of a string. This have already caused problems in the past, as far as I remember, but Ruby developers didn't change the behaviour of these characters. So if you write a regexp like /^[0-9]$/, a string "Any characters\n12345\nAny characters" will match the regexp.

> Ruby developers didn't change the behaviour of these characters

because Ruby has \A and \Z to match the boundaries of a string

Re: Arbitrary file execution in TZinfo (Ruby)

#17
For everyone who is panicking about this - to be affected, you either need to use a really old version of tzinfo (0.3.60 and earlier), have the tzinfo-data gem installed, or explicitly set TZInfo::DataSource to DataSources::RubyDataSource.

Otherwise, by default, tzinfo will use TZInfo::ZoneinfoDataSource, which does not seem to be affected.

https://github.com/tzinfo/tzinfo/blob/d9b289e1be30d29a2cb23b...

https://github.com/tzinfo/tzinfo/commit/b98c32efd61289fe6f00...

Re: Arbitrary file execution in TZinfo (Ruby)

#19

Earlier quoted context omitted.

It is a bug in tzinfo. It should not execute random files when given invalid timezone identifier. The app doesn't know what is a "valid" or "invalid" timezone, it is tzinfo's responsibility to check it. UPD: in fact tzinfo tried to validate a timezone identifier but did it the wrong way. It used a regular expression like /^...$/ and using ^ and $ is a mistake here. This allows to bypass validation by passing a multil…

Regex strikes again! I wonder how long it will take the computer industry to realise they just don't belong in code. Seems like most people still accept that they're hard to read and can't parse HTML but otherwise fine.

You're being downvoted and I agree that this is kind of overblown, but there is something here. This particular issue had nothing to do with readability specifically, but it had to do with the fact that the unpronounceable symbols ^ and $ had a specific meaning that was not what the devs expected. If we were using a more verbose pattern-matching DSL, we would probably have operators with names like "line_end" and "string_end", which don't require you to carefully cross-check the documentation in order to understand.

Personally I love regex, but only because I'm good at it and I generally have a good memory for obscure trivia.

Re: Arbitrary file execution in TZinfo (Ruby)

#20

Earlier quoted context omitted.

Regex strikes again! I wonder how long it will take the computer industry to realise they just don't belong in code. Seems like most people still accept that they're hard to read and can't parse HTML but otherwise fine.

You're being downvoted and I agree that this is kind of overblown, but there is something here. This particular issue had nothing to do with readability specifically, but it had to do with the fact that the unpronounceable symbols ^ and $ had a specific meaning that was not what the devs expected. If we were using a more verbose pattern-matching DSL, we would probably have operators with names like "line_end" and "st…

> but it had to do with the fact that the unpronounceable symbols ^ and $ had a specific meaning that was not what the devs expected.

What's worse is that ^ and $ have different meanings depending on whether you're using "single-line" or "multi-line" mode. From a quick web search, it seems Ruby always uses "multi-line" mode, while most other languages use "single-line" mode by default and have a flag to switch to "multi-line" mode. Someone who learned regex in other languages might not notice this difference, since most of the time the text being matched has no newlines, and so expect ^ and $ to match the boundaries of the text unless told otherwise by a "multi-line" flag.

Post reply on HN