Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable app that bricks the server after enabling #17451

Merged
merged 1 commit into from
Mar 1, 2016

Conversation

PVince81
Copy link
Contributor

@PVince81 PVince81 commented Jul 7, 2015

If an app is getting enabled in the web UI, an ajax call is now made to
make sure the server still works. If it doesn't, it sends an emergency
app disabling call to disable the breaking app.

Fix #17411

@Raydiation @oparoz @LukasReschke

@scrutinizer-notifier
Copy link

A new inspection was created.

@PVince81
Copy link
Contributor Author

PVince81 commented Jul 7, 2015

Note, this is a Proof Of Concept.

To test:

  1. Setup this branch for core
  2. Setup the calendar app, but use the "stable8" branch
  3. Remove the version restriction in the calendar app's info.xml
  4. Enable the calendar app in the web UI

Before this PR: it hangs, then OC is broken.
After this PR: app is disabled after the health check

@@ -848,6 +848,17 @@ public static function handleRequest() {
self::checkUpgrade();
}

// emergency app disabling
if ($request === '/disableapp' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['appid'])) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, a bit barbaric... is there a better way ?
This has to happen before the first call to OC_App::loadApps

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think thats fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest making it a GET parameter if possible, so the admin can open http://example.com/owncloud/disableapp?appid=broken-app manually if they refresh the page before the server health check completes (or if it breaks for some reason). Much easier than crafting a fake form to push a POST request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Xenopathic there are multiple browser addons that make POST a breeze.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET is definitely wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, OK.

@PVince81
Copy link
Contributor Author

PVince81 commented Jul 7, 2015

also @nickvergessen @icewind1991 @karlitschek @DeepDiver1975 for additional cheerfulness ? 😉

@PVince81
Copy link
Contributor Author

PVince81 commented Jul 7, 2015

Fixes #17435

@RobinMcCorkell
Copy link
Member

Fixes #18315

@MorrisJobke
Copy link
Contributor

Alternative approach #18599

@DeepDiver1975
Copy link
Member

@PVince81 needs rebase - 9.0 or later? THX

@@ -848,6 +848,17 @@ public static function handleRequest() {
self::checkUpgrade();
}

// emergency app disabling
if ($request === '/disableapp' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['appid'])) {
\OCP\JSON::checkAdminUser();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing CSRF check?

@PVince81 PVince81 added this to the 9.0-current milestone Feb 25, 2016
@PVince81 PVince81 self-assigned this Feb 25, 2016
@PVince81 PVince81 force-pushed the apps-disablebrokenappafterenable branch from 840eb1a to 8835076 Compare February 25, 2016 10:00
@PVince81
Copy link
Contributor Author

Rebased and adjusted.
Added CSRF check.

Please review @MorrisJobke @nickvergessen @rullzer @schiesbn @blizzz

To simulate a broken app, just edit "user_ldap/appinfo/app.php" and add a syntax error. Then try enabling the app.

@PVince81
Copy link
Contributor Author

Make sure to use https://github.com/owncloud/core/pull/17451/files?w=1 for the review, the JS code was mostly indented.

@MorrisJobke
Copy link
Contributor

Nice! Tested and works 👍

Also the code looks straight forward.

@rullzer
Copy link
Contributor

rullzer commented Feb 25, 2016

Does not seem to work over here... the error page just returns code 200 here...

// emergency app disabling
if ($requestPath === '/disableapp'
&& $request->getMethod() === 'POST'
&& $request->getParam('appid') !== ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default is null, which is !== '' so you will try to disable the app null, not sure what happens then, but should be adjusted:

((string) $request->getParam('appid')) !== ''

The casting to string is a good idea here anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the info, I wasn't sure either. Usually I'd do a isset on $_POST

@PVince81 PVince81 force-pushed the apps-disablebrokenappafterenable branch from 8835076 to f0b6c81 Compare February 29, 2016 10:32
@PVince81
Copy link
Contributor Author

@nickvergessen I added the string casting.

appId,
t('settings', 'Error: this app cannot be enabled because it makes the server unstable')
);
appItem.data('errormsg', t('settings', 'Error while disabling app'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while enabling?

If an app is getting enabled in the web UI, an ajax call is now made to
make sure the server still works. If it doesn't, it sends an emergency
app disabling call to disable the breaking app.
@PVince81 PVince81 force-pushed the apps-disablebrokenappafterenable branch from f0b6c81 to 1dbe240 Compare February 29, 2016 11:07
@PVince81
Copy link
Contributor Author

@nickvergessen fixed the error handling

@PVince81
Copy link
Contributor Author

@nickvergessen second review ?

@rullzer can you elaborate how you tested this ?

@nickvergessen
Copy link
Contributor

Works as expected, at least when the error is triggered in app.php or when displaying the files list.

👍

@PVince81
Copy link
Contributor Author

@rullzer mind giving it another test ? Would be good to know why it didn't work for you.

@rullzer
Copy link
Contributor

rullzer commented Feb 29, 2016

@PVince81 still not working as expected.

Steps I took.

  1. checkout branch 😉
  2. navigate to app page
  3. add some random noise into apps/user_ldap/appinfo/app.php
  4. enable app

The app does not get disabled.

I see the ajax call being made. And the error page is returned. But it just has a http status code of 200.

@PVince81
Copy link
Contributor Author

@rullzer hmmm, maybe your random noise produced different errors.

I just added some text like "test" in app.php in the middle of the code, technically a syntax error.

@PVince81
Copy link
Contributor Author

I remember that there are some cases where ownCloud would just return an exception page, and that page would return the status code 200. Maybe my detection code isn't accurate enough.

Another idea would be to query the capabilities API, which I suppose should also cover many cases.

@rullzer
Copy link
Contributor

rullzer commented Feb 29, 2016

@PVince81 I added "foo"... but that should not really matter

@PVince81
Copy link
Contributor Author

Ok got it, you added foo at the very top of the file.

I added it between some lines.

That causes another exception...

@PVince81
Copy link
Contributor Author

Actually, no. It doesn't brick ownCloud at all.
If you add foo before the <?php block then it's treated as content and likely ignored.

@rullzer please confirm / retest.

@rullzer
Copy link
Contributor

rullzer commented Feb 29, 2016

@PVince81 no I added it in the actual php code.

But I don't think the issue here is with your code actually. The issue is that the error page return HTTP status code 200...

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 1, 2016

@rullzer please post the diff of your change and also the exception from the error page you see.

@rullzer
Copy link
Contributor

rullzer commented Mar 1, 2016

The diff:

diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index dab47ee..d744979 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -25,7 +25,7 @@
  */

 OCP\App::registerAdmin('user_ldap', 'settings');
-
+foobar
 $helper = new \OCA\user_ldap\lib\Helper();
 $configPrefixes = $helper->getServerConfigurationPrefixes(true);
 $ldapWrapper = new OCA\user_ldap\lib\LDAP();

Error stuff:

Internal Server Error

The server encountered an internal error and was unable to complete your request.

Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.

More details can be found in the server log.

Technical details

    Remote Address: 127.0.0.1
    Request ID: cvvZM3EB/y+YC1aFMNTk
    Type: ParseError
    Code: 0
    Message: syntax error, unexpected '$helper' (T_VARIABLE)
    File: /home/roeland/oc/core/apps/user_ldap/appinfo/app.php
    Line: 29


Trace

#0 /home/roeland/oc/core/lib/private/app.php(145): OC_App::requireAppFile('user_ldap')
#1 /home/roeland/oc/core/lib/private/app.php(118): OC_App::loadApp('user_ldap')
#2 /home/roeland/oc/core/lib/base.php(849): OC_App::loadApps(Array)
#3 /home/roeland/oc/core/index.php(39): OC::handleRequest()
#4 {main}

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 1, 2016

@rullzer very strange... I get a proper 500 Internal Server Error even with your patch. Possibly an env difference.

@PVince81
Copy link
Contributor Author

PVince81 commented Mar 1, 2016

I applied this PR and your patch against 9.0beta2 and it also worked fine. Something seems wrong in your env.

Let's move forward and merge this.

DeepDiver1975 added a commit that referenced this pull request Mar 1, 2016
Disable app that bricks the server after enabling
@DeepDiver1975 DeepDiver1975 merged commit 256dfd2 into master Mar 1, 2016
@DeepDiver1975 DeepDiver1975 deleted the apps-disablebrokenappafterenable branch March 1, 2016 10:26
@lock
Copy link

lock bot commented Aug 7, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Apps Management] enabling an incompatible app results in broken installation
9 participants