Security Patch SUPEE-7405 - Possible Problems?
-
09-12-2020 - |
سؤال
It's time for another patch day, SUPEE-7405 for Magento 1.x is out and the list of fixes is long: https://magento.com/security/patches/supee-7405
After the experience with the last patches, I have to ask again: what are the possible problems when applying the patch and what do I need to consider?
Lots of XSS issues were fixed again, so I expect to patch custom themes manually. Anything else? Are there backward incompatible changes?
المحلول
23rd February 2016 Update: The patch has been updated to V1.1, which fixes a number of important issues listed in this post, here is the list:
- Cart Merge Patch (SUPEE-7978) : Carts with identical items now merge correctly. Previously, when a cart with one item was merged with another cart that contained the same item, Magento did not merge the cart totals correctly. The cart now includes only one item, and the total is correct.
- SOAP API Patch (SUPEE-7822) : The Magento SOAP API now works as expected. Previously after installing the SUPEE-7405 v1.0 patch, an API request would cause a 500 error, and Magento would log an exception.
- PHP 5.3 Compatibility (SUPEE-7882) : The patch was not compatible with PHP 5.3 for earlier versions of Magento that were still supporting this version. Merchants experiencing this issue were unable to view sales information in the Admin.
- Upload File Permissions : The patch restores less restrictive file permissions (0666 for files and 0777 for directories) as more strict permissions introduced by the original SUPEE-7405 patch caused many merchants not to be able to view uploaded product images, depending on hosting provider configuration.
After digging into the patch, here are the relevant / interesting things I've found (N.B.: this list has been made by analyzing the patch for CE 1.9.2.0-1.9.2.2, there's probably more for patches affecting older versions of Magento) :
- (fixed in V1.1 of the patch)
The use of[]
instead ofarray()
in this patch makes it backward incompatible with PHP < 5.4 (see known issues below) - As stated, most of the changes are html escaping and data sanitizing regarding XSS issues.
- Form key validation has been added to the admin login in
Mage_Admin_Model_Observer
- Form key validation has been added to the admin forgot password in
Mage_Adminhtml_IndexController
- Form key validation has been added to the admin reset password in
Mage_Adminhtml_IndexController
- Form key validation has been added to the frontend cart delete action. Form key is added to the
getDeleteUrl
ofMage_Checkout_Block_Cart_Item_Renderer
and validated in thedeleteAction
ofMage_Checkout_CartController
. - Events are now dispatched all lower case (every config files affected have been modified e.g.
controller_action_postdispatch_checkout_onepage_saveOrder
becomescontroller_action_postdispatch_checkout_onepage_saveorder
). This does not affect your local observers configuration. More information here: https://twitter.com/foomanNZ/status/689924329065164800 - A new validator to check if an uploaded file is an image has been added:
Mage_Core_Model_File_Validator_Image
- A new Import/Export section appears :
System => Configuration =>Advanced > System => Escape CSV Fields
- New event dispatched:
admin_user_validate
underMage_Admin_Model_User
- SVG is not a valid favicon extension anymore
- For those using Authorizenet (I don't) it seems like a few changes have been made, not sure how it impacts the system though. Changes include a new admin helper (
Mage_Authorizenet_Helper_Admin
) used to get the success order url. - New Zend class:
Zend_Xml_Security
. Its purpose is to scan XML string for potential XXE and XEE attacks. However I did not find any reference to it in the other modified files. - Files uploaded via admin panel (i.e. product image upload) are now not world readable by default (before: 777 / after: 640).
- Directories are also not world executable (before 755 / after: 750). This two can cause issues with images not appearing on the website if the webserver runs as a different user from php (credits: @Rob Mangiafico)
- Regarding frontend templates: the only modifications made are data escaping, which are not system breakers but still recommended to implement on your custom theme (and there's only two frontend files affected not that much work ;) )
Known issues after patching:
I'll try to keep this list as up to date as possible.
Before starting a new issue/question, please ensure you've applied all the previous patches as it seems like a lot of issues comes from missing patches.
Another thing is: if you have modified core files, applying the patch may fail. If you're having a Hunk # failed at
error for a specific file and you're 100% sure you've applied all the previous patches, please ensure you have the original file from your Magento version by checking the mirror: https://github.com/OpenMage/magento-mirror/
- Dropped sessions issue (with fix) (https://magento.stackexchange.com/a/116324/2380)
- Unable to login to the backend after the patch: "Invalid form key" error. => Flush your browser cookies and delete the var/session files (Magento 1.9.2.3. not login in google chrome)
- (fixed in v1.1 of the patch)
Admin order view page is blank / broken => Related to the PHP < 5.4 incompatibility. => Fix can be found here: https://magento.stackexchange.com/a/98237/2380 / I've created a bug report: https://www.magentocommerce.com/bug-tracking/issue/index/id/1266 (credits: @Moonman67). - (fixed in v1.1 of the patch)
SOAP API URL/index.php/api/v2_soap/index/?wsdl=1
throws a 500 error => I've developped a hacky fix for this one that can be found here: https://magento.stackexchange.com/a/98790/2380 / I've also created a bug report for this one: https://www.magentocommerce.com/bug-tracking/issue/index/id/1265 (credits: @Moonman67) - (fixed in v1.1 of the patch)
Issues regarding file upload permissions - Applying patch on Magento 1.7.0.0 breaks: https://magento.stackexchange.com/a/98246/2380
- Checkout not redirecting to success page on HHVM: https://magento.stackexchange.com/a/98334/2380
- Undefined class constant AREA ADMINHTML in
app/code/core/Mage/Core/Model/Config.php
(possibly EE only): SUPEE 7405 Enterprise Edition Fatal error Undefined class constant 'AREA_ADMINHTML - Call to undefined method
Mage_Core_Helper_Abstract::escapeHtml()
on 1.4.0.1 : Error after installing patch 7405 on Magento 1.4.0.1 - Mage registry key
_singleton/Mage_Core_Model_Domainpolicy
already exists on Magento 1.7: Security Patch SUPEE-7405 Error - Call to a member function getUsername() on a non-object after the patch: Magento Admin thrown error after applying SUPEE 7405 security patch
- Unable to add permission block after patch on 1.8.1.0 : After Security patch supee-7405 topmenu is not displaying
- (Previous patch not applied)
Issues applying the patch on 1.7.0.2 : Security Patch SUPEE-7405 Issues - (Core files had been changed)
Issues applying the patch on 1.8.1 : supee 7405 Hunk #2 FAILED at 472. Magento 1.8.1 - (Provider related)
Email queue broken after patch : Magento 1.9.2.3 Email-Queue not working
List of affected files
It can be found on this page here: https://magento.stackexchange.com/a/98232/2380 (credits @MagenX)
EE Only
- If you updated from Magento EE 1.14.2.x to Magento EE 1.14.2.3 instead of applying the patch, and also applied the support patch SUPEE-5984 before, you have to reapply it again because it is not included in the release. => https://magento.stackexchange.com/a/98805/2380
Regarding Patch 7616:
- Seems like patches 4291 and 6237 need to be applied before applying the patch. More information here: Apply 7616_EE 7405_EE patch not successfuly
- (Patch 5344 had not been applied)
Possible problem when applying 7616 before applying 7405: SUPEE 7405 - Hunk #2 Failed at 43
Good resources about Magento patches
- Critical Reminder: Download and install Magento security patches. (FTP with no SSH access)
- Mage Report has added a check for SUPEE-7405: https://www.magereport.com/
Feel free to let me know if I miss something.
نصائح أخرى
One issue I have noticed is that if your site is using a version less than PHP 5.4 the patch is not compatible.
In the class Mage_Adminhtml_Helper_Sales
around line number 124. The code is:
$links = [];
I needed to extend this to be:
// Patch not compatible with PHP version 5.3: overwrote Magento patch update
$links = array();
Another error I ran into seemed to involve the cookies I had set. Once I cleared my cookies though, all pages have been loading fine.
Example Error:
Notice: unserialize() [function.unserialize]: Error at offset 0 of 13 bytes in `/var/www/website/app/code/core/Mage/Core/Helper/Cookie.php` on line 83
I'm not sure if anyone else has run into these issues, but hope it helps!
Here's a problem I've found when patching Magento CE with SUPEE-7405. It replaces the line:
chmod($destinationFile, 0777);
with:
chmod($destinationFile, 0640);
in the file lib/Varien/File/Uploader.php
This stopped my images displaying in the back end, since this file permission should actually be 644. Is there any reason this has been set to 640?
When applying for Magento 1.7.0.0 its trying to remove a comment on app/design/adminhtml/default/default/template/authorizenet/directpost/iframe.phtml
-/* @var $_helper Mage_Authorizenet_Helper_Data */
that was not added until 1.7.0.1 https://raw.githubusercontent.com/OpenMage/magento-mirror/1.7.0.1/app/design/adminhtml/default/default/template/authorizenet/directpost/iframe.phtml
these files patched, you can see any possible impact:
template: admin templates mostly patched.
+++ app/design/frontend/base/default/template/rss/order/details.phtml
+++ app/design/frontend/base/default/template/catalog/product/view/options/type/file.phtml
+++ app/design/adminhtml/default/default/template/sales/order/view/info.phtml
+++ app/design/adminhtml/default/default/template/sales/order/totals/discount.phtml
+++ app/design/adminhtml/default/default/template/sales/items/renderer/default.phtml
+++ app/design/adminhtml/default/default/template/sales/items/column/name.phtml
+++ app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/name.phtml
+++ app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/invoice/name.phtml
+++ app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/creditmemo/name.phtml
+++ app/design/adminhtml/default/default/template/catalog/product/composite/fieldset/options/type/file.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/shipment/view/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/shipment/create/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/order/view/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/invoice/view/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/invoice/create/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/creditmemo/view/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/bundle/sales/creditmemo/create/items/renderer.phtml
+++ app/design/adminhtml/default/default/template/authorizenet/directpost/iframe.phtml
core/libs:
+++ lib/Varien/Io/File.php
+++ lib/Varien/File/Uploader.php
+++ app/code/core/Zend/Xml/Security.php
+++ app/code/core/Mage/Sales/Model/Quote/Item.php
+++ app/code/core/Mage/Sales/Model/Quote/Address.php
+++ app/code/core/Mage/Sales/Helper/Guest.php
+++ app/code/core/Mage/Rss/Helper/Order.php
+++ app/code/core/Mage/Rss/Block/Catalog/Salesrule.php
+++ app/code/core/Mage/Review/controllers/ProductController.php
+++ app/code/core/Mage/Paypal/controllers/PayflowadvancedController.php
+++ app/code/core/Mage/Paypal/controllers/PayflowController.php
+++ app/code/core/Mage/Newsletter/Model/Queue.php
+++ app/code/core/Mage/Newsletter/Model/Observer.php
+++ app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php
+++ app/code/core/Mage/ImportExport/Model/Export/Adapter/Csv.php
+++ app/code/core/Mage/ImportExport/Model/Export/Adapter/Abstract.php
+++ app/code/core/Mage/Downloadable/controllers/CustomerController.php
+++ app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php
+++ app/code/core/Mage/Customer/controllers/AccountController.php
+++ app/code/core/Mage/Core/Model/Session.php
+++ app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php
+++ app/code/core/Mage/Core/Model/File/Validator/Image.php
+++ app/code/core/Mage/Core/Model/Email/Template/Filter.php
+++ app/code/core/Mage/Core/Model/Email/Queue.php
+++ app/code/core/Mage/Core/Model/Config.php
+++ app/code/core/Mage/Core/Model/App.php
+++ app/code/core/Mage/Core/Helper/Data.php
+++ app/code/core/Mage/Checkout/controllers/OnepageController.php
+++ app/code/core/Mage/Checkout/controllers/CartController.php
+++ app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php
+++ app/code/core/Mage/CatalogInventory/Helper/Minsaleqty.php
+++ app/code/core/Mage/Catalog/Model/Resource/Product/Attribute/Backend/Image.php
+++ app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
+++ app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php
+++ app/code/core/Mage/Authorizenet/controllers/Adminhtml/Authorizenet/Directpost/PaymentController.php
+++ app/code/core/Mage/Authorizenet/Helper/Data.php
+++ app/code/core/Mage/Authorizenet/Helper/Admin.php
+++ app/code/core/Mage/Adminhtml/controllers/IndexController.php
+++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Image/Favicon.php
+++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Image.php
+++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/File.php
+++ app/code/core/Mage/Adminhtml/Helper/Sales.php
+++ app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php
+++ app/code/core/Mage/Adminhtml/Block/Widget/Grid.php
+++ app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Tab/History.php
+++ app/code/core/Mage/Admin/Model/User.php
+++ app/code/core/Mage/Admin/Model/Resource/User.php
+++ app/code/core/Mage/Admin/Model/Redirectpolicy.php
+++ app/code/core/Mage/Admin/Model/Observer.php
========================================================================= p.s. just to keep all together, we have created some "no-brainer" multipatch to patch many servers with multiple magento installations. multipatch-7405.sh
Here is my basic test plan:
- Apply coupon
- Login to admin
- Force admin to change password
- Export a CSV
- Import a CSV
- Reset password as admin and customer
- Create an order in admin
- Create and order in the front-end as guest
- Create and order in the front-end as customer
- Add an image to a product
- Create a credit memo
- Create an invoice
Please be aware of dropped sessions issue recently discovered and fixed (?) by Colin Mollenhour.
https://gist.github.com/colinmollenhour/5066a3220881a9c0c2dd42fa1593cbff/revisions
If you updated from Magento EE 1.14.2.x to Magento EE 1.14.2.3 instead of applying the patch, and also applied the support patch SUPEE-5984 before, you have to reapply it again because it is not included in the release.
This was the patch that fixed the broken indexer: Index error after upgrade to EE 1.14.2.0: table catalog_product_entity_tmp_indexer doesn't exist
As of Feb 23 2016, Magento have released a patch for the patch to address many of these problems: https://magento.com/security/patches/supee-7405
You need to apply SUPEE_7405_v1 then SUPEE_7405_v1.1 in order.
Whenever we install a patch for one of our clients we use the following checklist:
- Make a complete backup of the site files & database.
- Make sure all previous patches have been installed successfully (can be seen in
app/etc/applied.patches.list
file) - After successful installation of the patch, clear the cache and make a test order to ensure everything works.
I guess that's really all there is to it. The patches are designed to be installed quickly and without any hassle. 9 out of 10 times they will install perfectly fine and for the other times we have backups. As long as you are not messing with core files everything should be okay.
here affected files for Magento EE
> -e 2016-02-11 03:14:54 UTC | SUPEE-7405-EE-1-14-2-2 | EE_1.14.2.2 | v1 | 91465c744a824111902e2911fd63fd8cb6c32f05 | Tue Jan 19 14:27:03 2016 +0200 | e1fc3c59c9..91465c744a
patching file app/code/core/Enterprise/Checkout/Block/Adminhtml/Manage/Form/Coupon.php
patching file app/code/core/Enterprise/GoogleAnalyticsUniversal/Block/Ga.php
patching file app/code/core/Enterprise/PageCache/etc/config.xml
patching file app/code/core/Enterprise/Pbridge/etc/config.xml
patching file app/code/core/Enterprise/Pci/Model/Observer.php
patching file app/code/core/Enterprise/Pci/Model/Resource/Admin/User.php
patching file app/code/core/Enterprise/Pci/etc/config.xml
patching file app/code/core/Enterprise/Persistent/etc/config.xml
patching file app/code/core/Enterprise/SalesArchive/etc/config.xml
patching file app/code/core/Enterprise/WebsiteRestriction/etc/config.xml
patching file app/code/core/Mage/Admin/Model/Observer.php
patching file app/code/core/Mage/Admin/Model/Redirectpolicy.php
patching file app/code/core/Mage/Admin/Model/Resource/User.php
patching file app/code/core/Mage/Admin/Model/User.php
patching file app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Tab/History.php
patching file app/code/core/Mage/Adminhtml/Block/Widget/Grid.php
patching file app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php
patching file app/code/core/Mage/Adminhtml/Helper/Sales.php
patching file app/code/core/Mage/Adminhtml/Model/System/Config/Backend/File.php
patching file app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Image.php
patching file app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Image/Favicon.php
patching file app/code/core/Mage/Adminhtml/controllers/IndexController.php
patching file app/code/core/Mage/Authorizenet/Helper/Admin.php
patching file app/code/core/Mage/Authorizenet/Helper/Data.php
patching file app/code/core/Mage/Authorizenet/controllers/Adminhtml/Authorizenet/Directpost/PaymentController.php
patching file app/code/core/Mage/Captcha/etc/config.xml
patching file app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php
patching file app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
patching file app/code/core/Mage/Catalog/Model/Resource/Product/Attribute/Backend/Image.php
patching file app/code/core/Mage/CatalogIndex/etc/config.xml
patching file app/code/core/Mage/CatalogInventory/Helper/Minsaleqty.php
patching file app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php
patching file app/code/core/Mage/Checkout/controllers/CartController.php
patching file app/code/core/Mage/Checkout/controllers/OnepageController.php
patching file app/code/core/Mage/Core/Helper/Data.php
patching file app/code/core/Mage/Core/Model/App.php
patching file app/code/core/Mage/Core/Model/Config.php
patching file app/code/core/Mage/Core/Model/Email/Queue.php
patching file app/code/core/Mage/Core/Model/Email/Template/Filter.php
patching file app/code/core/Mage/Core/Model/File/Validator/Image.php
patching file app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php
patching file app/code/core/Mage/Core/Model/Session.php
patching file app/code/core/Mage/Customer/controllers/AccountController.php
patching file app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php
patching file app/code/core/Mage/Downloadable/controllers/CustomerController.php
patching file app/code/core/Mage/ImportExport/Model/Export/Adapter/Abstract.php
patching file app/code/core/Mage/ImportExport/Model/Export/Adapter/Csv.php
patching file app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php
patching file app/code/core/Mage/ImportExport/etc/config.xml
patching file app/code/core/Mage/ImportExport/etc/system.xml
patching file app/code/core/Mage/Newsletter/Model/Observer.php
patching file app/code/core/Mage/Newsletter/Model/Queue.php
patching file app/code/core/Mage/Page/etc/system.xml
patching file app/code/core/Mage/Paypal/controllers/PayflowController.php
patching file app/code/core/Mage/Paypal/controllers/PayflowadvancedController.php
patching file app/code/core/Mage/Paypal/etc/config.xml
patching file app/code/core/Mage/Persistent/etc/config.xml
patching file app/code/core/Mage/Review/controllers/ProductController.php
patching file app/code/core/Mage/Rss/Block/Catalog/Salesrule.php
patching file app/code/core/Mage/Rss/Helper/Order.php
patching file app/code/core/Mage/Sales/Helper/Guest.php
patching file app/code/core/Mage/Sales/Model/Quote/Address.php
patching file app/code/core/Mage/Sales/Model/Quote/Item.php
patching file app/code/core/Zend/Xml/Security.php
patching file app/design/adminhtml/default/default/template/authorizenet/directpost/iframe.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/creditmemo/create/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/creditmemo/view/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/invoice/create/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/invoice/view/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/order/view/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/shipment/create/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/bundle/sales/shipment/view/items/renderer.phtml
patching file app/design/adminhtml/default/default/template/catalog/product/composite/fieldset/options/type/file.phtml
patching file app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/creditmemo/name.phtml
patching file app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/invoice/name.phtml
patching file app/design/adminhtml/default/default/template/downloadable/sales/items/column/downloadable/name.phtml
patching file app/design/adminhtml/default/default/template/enterprise/checkout/form/coupon.phtml
patching file app/design/adminhtml/default/default/template/sales/items/column/name.phtml
patching file app/design/adminhtml/default/default/template/sales/items/renderer/default.phtml
patching file app/design/adminhtml/default/default/template/sales/order/totals/discount.phtml
patching file app/design/adminhtml/default/default/template/sales/order/view/info.phtml
patching file app/design/frontend/base/default/template/catalog/product/view/options/type/file.phtml
patching file app/design/frontend/base/default/template/rss/order/details.phtml
patching file lib/Varien/File/Uploader.php
patching file lib/Varien/Io/File.php
After applying the SUPEE-7405 on Magento 1.14.1.0 I got the error:
Fatal error: Cannot redeclare Mage_Core_Controller_Varien_Router_Admin::_validateControllerInstance() in app/code/core/Mage/Core/Controller/Varien/Router/Admin.php on line 173
The problem was caused by re-declared method _validateControllerInstance in
app/code/core/Mage/Core/Controller/Varien/Router/Admin.php on line 173
After removing second (same) function declaration, the issue has been solved.
I got following error after installing the SUPEE-7405 patch when try to login to admin.
Fatal error: Call to undefined method Mage_Core_Controller_Response_Http::sendHeadersAndExit() in
\app\code\core\Mage\Admin\Model\Session.php on line 135
because I had this file overridden in local code pool which does not have
sendHeadersAndExit
method created by this patch.
\app\code\local\Mage\Core\Controller\Response\Http.php
following method does not exist. ( This is a new method added to the core file)
/**
* Method send already collected headers and exit from script
*/
public function sendHeadersAndExit()
{
$this->sendHeaders();
exit;
}
After adding this to the overridden file issue gone away.
One of the issues I got when using SUPEE-7405 is Image Upload Bugs
Therefore, I check the changes in this file: lib/Varien/File/Uploader.php
diff --git lib/Varien/File/Uploader.php lib/Varien/File/Uploader.php --- --- - chmod($destinationFile, 0777); + chmod($destinationFile, 0640); --- --- - if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0777, true))){ + if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0750, true))){
Then, I found out two ways to overcome it:
Option 1:
I perform a manual change on the file the file lib/Varien/File/Uploader.php to adjust the 0640/0750 permissions.
Option 2: Because Magento expects the webserver to own the site files:
http://devdocs.magento.com/guides/m1x/install/installer-privileges_after.html#privs-after
The other way to resolve the problem is making the webserver the owner of the files
chown -R web-server-user-name magento/root/path
The webserver user name is commonly www-data or apache.