-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Conversation
A new inspection was created. |
Note, this is a Proof Of Concept. To test:
Before this PR: it hangs, then OC is broken. |
@@ -848,6 +848,17 @@ public static function handleRequest() { | |||
self::checkUpgrade(); | |||
} | |||
|
|||
// emergency app disabling | |||
if ($request === '/disableapp' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['appid'])) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think thats fine.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GET is definitely wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, OK.
also @nickvergessen @icewind1991 @karlitschek @DeepDiver1975 for additional cheerfulness ? 😉 |
Fixes #17435 |
Fixes #18315 |
Alternative approach #18599 |
@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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing CSRF check?
840eb1a
to
8835076
Compare
Rebased and adjusted. 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. |
Make sure to use https://github.com/owncloud/core/pull/17451/files?w=1 for the review, the JS code was mostly indented. |
Nice! Tested and works 👍 Also the code looks straight forward. |
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') !== '' |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
8835076
to
f0b6c81
Compare
@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')); |
There was a problem hiding this comment.
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.
f0b6c81
to
1dbe240
Compare
@nickvergessen fixed the error handling |
@nickvergessen second review ? @rullzer can you elaborate how you tested this ? |
Works as expected, at least when the error is triggered in app.php or when displaying the files list. 👍 |
@rullzer mind giving it another test ? Would be good to know why it didn't work for you. |
@PVince81 still not working as expected. Steps I took.
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. |
@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. |
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. |
@PVince81 I added "foo"... but that should not really matter |
Ok got it, you added I added it between some lines. That causes another exception... |
Actually, no. It doesn't brick ownCloud at all. @rullzer please confirm / retest. |
@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... |
@rullzer please post the diff of your change and also the exception from the error page you see. |
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:
|
@rullzer very strange... I get a proper 500 Internal Server Error even with your patch. Possibly an env difference. |
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. |
Disable app that bricks the server after enabling
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. |
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