While thinking more about #605318: Add some garbage collection to the update manager and after more internal test I found another bug that could lead to WSOD's and XSS security issues if people upgrading their modules.
1. update_manager_archive_extract() does not remove stale directories in temporary://update-extraction before extracting the module archives.
2. In such a case a version beta1 can have files that are not removed by beta2, but here they are kept on disk.
3. If beta 1 had an security issue in a file that will be removed in beta2 the file still reside on the disk and is never removed. (except by garbage collection, but this is not reliable)
4. If beta2 is downloaded after beta1, it get's extracted to temporary://update-extraction and than copied over the additional and unused files to sites/all/modules/[module-name]
We need to delete the modules directory in temporary://update-extraction before extracting a new release and also make sure the directory sites/all/modules/[module-name] is deleted before the copy over from temporary://update-extraction/[module-name].
NOTE: If someone have manually installed a lib inside a modules directory this one get's deleted if we remove the folder in sites/all/modules/[module-name]. This can be seen as by design, but should be noted as a bug in a module.
| Comment | File | Size | Author |
|---|---|---|---|
| #24 | Screengrab 1 | 47.88 KB | Tor Arne Thune |
| #24 | Screengrab 2 | 95.52 KB | Tor Arne Thune |
| #17 | 977408-16.update-manager-remove-extraction-target-dir.patch | 1.19 KB | dww |
| #14 | funny_file_name.patch | 957 bytes | hass |
| #13 | 977408_update-extraction_bug-D7.patch | 957 bytes | hass |
Comments
Comment #1
hass commentedAuthorize.php does not have this bug. It's only in update manager as it does not kill the folder before extraction.
Comment #2
hass commentedHere is a patch to fix this bug.
Comment #3
hass commentedNew patch. I only changed the name of the $project_location variables to $extract_location what makes code easier to read.
Comment #4
tstoecklerfolder -> directory.
Also I don't think we need to explain our recommended best practice here.
Maybe just:
"Remove the directory if it exists."
Otherwise looks good, although I haven't looked at the surrounding code.
Powered by Dreditor.
Comment #5
hass commentedWhat's wrong with "folder"? As nobody implemented it it needs to be explained or we would't have so many bugs in the update module.
Comment #6
tstoecklerWell, I don't really care. This is a critical so let's get some more reviews on the actual code.
Comment #7
hass commentedComment #8
dries commentedThe code comment is not really clear. Is it proper English to begin with?
Comment #9
shaundychkoTry:
Remove the folder if it exists, otherwise it will contain a mixture of old outdated files mixed with the shiny new files.
Comment #10
hadi farnoud commented#3: 977408_update-extraction_bug-D7.patch queued for re-testing.
Comment #11
hass commentedReplaced comment with text from #9, nothing else has been changed.
Comment #12
hass commentedAnd here is a "directory" version if you do not like "folder".
Comment #13
hass commentedwhy does d.o ignore the files?
Comment #14
hass commentedAnd here is a "directory" version if you do not like "folder".
Comment #15
cosmicdreams commentedHmm... issue thread already has a status of needs review... Testbot just needs to wake up?
Comment #16
hass commentedLatest patch is in #14. I guess the test bot have issues with file naming... not the first time I've seen this annoying issue.
Comment #17
dwwSee #973432: D6 patches named -D6 are not tested for what the file naming convention was changed. See also the help text on the file attachment form element. ;)
Re-rolled the patch to fix the comment (wrap to 80 chars, more clear text).
I was a little worried about removing the directory like this since someone could do a lot of damage by calling update_manager_archive_extract() with the wrong arguments. In the FileTransfer classes, we have a bunch of code to enforce that operations are only happening inside a "jail", so you don't accidentally go off removing files from other parts of the filesystem that you shouldn't be touching. However, all of this code is happening in the Update manager before we reach authorize.php (so we don't have a FileTransfer class at all). Furthermore, this is just the local temp directory where we extract and verify the archive, not when we're touching the live code. Finally, we're about to clobber the directory by extracting the archive, this is just a cleaner way to do it without any surprises. I also audited the code to see all the call sites, and we're definitely invoking this function properly.
This is definitely a security hardening patch, since if someone can trick the web server to write malicious files into this extraction location (which the OS permissions will allow), those malicious files would be installed the next time Update manager was trying to update/install a module. This way, we ensure that the only files in the extraction directory are those that were in the archive. Of course, there's still a race condition and a window of time when the extracted files are still sitting there after they've been verified and before they've been installed, but at least with this patch, that window is a lot smaller.
I haven't re-tested with this patch, but I wanted to post it now to get the bot started on it. Not that we have any test coverage for these code paths. :( So, the bot isn't going to tell us much. This really needs thorough manual testing before it's truly RTBC.
Comment #18
dwwOh, and by the definitions in #974066: Friendly reminder: on critical issues and RCs and elsewhere, this isn't critical. It's still a major security hardening patch, but it doesn't impact the string freeze and could be fixed after an RC. I'd rather see it fixed now, but we shouldn't abuse the critical status.
Comment #19
dwwNote: I manually tested this and it works as expected. I'd be willing to call this RTBC, but since technically the last patch was mine, I can't really do that. Hopefully once the bot confirms the patch applies cleanly (about all it's going to be able to tell us), someone should give this a final look and RTBC.
Comment #20
cosmicdreams commentedI finally have a break in the storm of seasonal work. I'll be online tonight to test everything I can and will make this my first target.
Comment #21
cosmicdreams commentedPre-test:
updated to fresh cvs version and checked to see if I needed to do any db updates.
Test #1: Before patch
* checked to see if I had any updates to install for any of the modules I had previous installed : found 2
- Drupal Core (obviously)
- Zen Theme
* Checked the option to install the Zen Theme
* Update downloaded successfully
* Chose option to install the update in maintenance mode.
* Entered proper credentials to update via ftp. Submitted form
* Received HTTP Error 324 (ERR_EMPTY_RESPONSE) from chrome (as usual)
* checked the update-cache and update-extraction folders. Found that there was no zen folder in either.
Test #2; After patch
* Retried update for Zen theme
* followed the same steps as above
* Received HTTP error 324 (ERR_EMPTY_RESPONSE) from chrome (no change)
* check the update-cache and update-extraction folders (this time before and after the upgrade event) there was no zen folder created at either time.
Comment #22
hass commentedThis is not what this patch is made for.
How you can test this patch or the bug without the patch...
1. Install Devel beta 1
2. Put some dummy files (doesn't matter what) into update-extraction/devel
3. Now update to Devel beta 2
4. Verify that the dummy files are now not copied into sites/all/modules/devel directory (without the patch the files would be inside sites/all/modules/devel).
The last is very problematic if you have module that removes files in future version or change it's directory structure as it can break a module (e.g if it dynamically include files in subdirectories based on module names, ctools my be e candidate) aside from files that are kept on disk (possible security issues).
I checked dww's patch and it only changed documentation and nothing on the code. As I have tested this myself and developed it and I guess I cannot set it RTBC, but it is from my point of view.
Comment #23
cosmicdreams commentedOK, I'll test that today.
Comment #24
Tor Arne Thune commentedTested #17 and it is working as hass described in #22.
Xubuntu 10.10
Apache 2.2.16
PHP 5.3.3
MySQL 5.1.49
Steps used to test:
The file "junkFile.txt" is not in the "devel" folder inside the "update-extraction" folder (see Screengrab 2.)
The file "junkFile.txt" is not in the "devel" folder inside the "sites/all/modules" folder (see Screengrab 2.)
I'm not setting the status to RTBC because of dww's comment in #17:
Maybe the code needs a review too? I can't do this.
Comment #25
hass commentedRTBC?
Comment #26
aspilicious commentedWTF? This is alrdy fixed, I'm prety sure cause I saw that piece of code in my zip debug sprint...
EDIT
----
fixed?
Comment #27
aspilicious commentedfixed!
Comment #28
Tor Arne Thune commentedYou are right. It is fixed. I checked out HEAD from CVS and checked the file manually. The code in update.manager.inc is the same as in the patch in #17. Thanks for catching this.
Comment #29
dwwTee heeeeeeeee.... ;) WHOOPS!
I accidentally included this fix in my final patch for #609772-50: Impossible to extend the FileTransfer class system in contrib, which no one noticed, and webchick happily committed it.
I'll check with her in IRC right now if she wants to do anything about this. I vote for leaving it fixed instead of re-breaking it and then fixing it again.