Posted by dropcube on August 19, 2009 at 9:23pm
9 followers
| Project: | Drupal core |
| Version: | 7.x-dev |
| Component: | simpletest.module |
| Category: | bug report |
| Priority: | critical |
| Assigned: | boombatower |
| Status: | closed (fixed) |
| Issue tags: | security |
Issue Summary
For example, when running "Enable/disable modules" test, a 403 Access denied error is reported.
Comments
#1
If a request is redirected to other URL (with a drupal_goto() for example), the same User Agent is passed to the other request, including the request time. If there are multiple redirects, the time window will be lower, and the check in
check in drupal_valid_test_ua()might fail.#2
subscribing
#3
Subscribing. Need to fix this to turn testing bot back on.
#4
Apparently it causes these specific errors when the modules page doesn't save properly. I can confirm the problem is intermittent, happens on slower testing systems (quad core or worse) and can happen on either PIFR 1 or PIFR 2. It's line 117 that cascades into more errors because it's where the post to save the modules page happens.
CSV simpletest table dump:
#5
I develop on a very slow machine, and I'm getting the same failures also for ModuleDependencyTestCase::testEnableWithoutDependency(), which equally tries to post to the module page.
#6
But even when doing
--- modules/simpletest/drupal_web_test_case.php 17 Aug 2009 19:14:41 -0000 1.137+++ modules/simpletest/drupal_web_test_case.php 20 Aug 2009 00:17:00 -0000
@@ -31,7 +31,7 @@ abstract class DrupalTestCase {
/**
* Time limit for the test.
*/
- protected $timeLimit = 180;
+ protected $timeLimit = 0;
I'm still getting the same errors. I'm rather confused by the returned 403.
#7
I am assuming this is due to:
<?phpcase DRUPAL_BOOTSTRAP_DATABASE:
// The user agent header is used to pass a database prefix in the request when
// running tests. However, for security reasons, it is imperative that we
// validate we ourselves made the request.
if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], "simpletest") !== FALSE) && !drupal_valid_test_ua($_SERVER['HTTP_USER_AGENT'])) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
exit;
}
?>
Attempting to fix.
#8
Confirmed by changing the time window in drupal_valid_test_ua().
Supposed to generate a new one every request in curlInitialize(), but curl is handling the redirect since drupal_goto() returns a "Location" header.
This can be fixed by: a) increasing the time window, or b) turning off the auto redirect in curl and doing it ourselves.
#9
@sun: The returned 403 is due to
drupal_valid_test_ua()time window check. If the time window is consumed in the page process, and a redirection occurs, then the time diff doesn't fit in the time window of the next request.We have these options:
1- Do NOT validate against a time window.
2- Regenerate a new user agent for requests started by simpletest. When the request is redirect, i.e. using drupal_goto(), regenerate a new user agent with the current time instead of the request time.
Option 1 is quicker as easier to implement for now. The attached patch fixes it.
#10
#11
Remove curl redirect follow and implements inside DWTC.
#12
#14
#15
I still kind of like #9 as part of the solution to this. The whole 2 second check thing seems arbitrary. Why not just let it take as long as it takes in case the server happened to have some combination of high CPU, disk I/O, swapping, etc misc load. It's not like the 2 second window has some sort of runaway process kill functionality in it which might be the only useful part of having a counter on it...
#16
Let's fix the bug first. That's highly critical, because it blocks many patches and code-freeze is coming.
#17
Great sleuthing, folks!
Ok, switching testing bot back on....
#18
Hm. Damn. No dice.
All of the patches that make it as far as running tests are getting the same failures. Random example:
http://testing.drupal.org/pifr/file/1/11678
Result received from slave #38 (Failed: 13069 passes, 15 fails, 4 exceptions).
Path aliases with translated nodes: 1 fail, 1 exception
Session tests: 1 fail
SimpleTest functionality: 4 fails, 1 exception
UI language negotiation: 9 fails, 2 exceptions
#19
ok, testbot seems to fail on tests that may expect special treatment of redirects: http://testing.drupal.org/pifr/file/1/11677
#20
#21
Also, I decided to revert the previous patch. It might be close, but the situation before the patch was that under some conditions some machines might get 3 failures in the module tests, and the situation after is all machines are getting 15 failures in a number of seemingly unrelated tests. This stage of the core development cycle is the most critical, and I don't want to see core developers wasting time debugging things that are not their fault.
If there's a way to do a dry run on the testing servers with the next patch before it gets marked RTBC, I would really appreciate it. ;)
#22
What's funny is the easiest way to test before would have been to have PIFR 2 to it, but I moved all the clients except my sandbox back to PIFR 1. Maybe amazon will come through with some additional clients.
#23
Er, nevermind. It'll have to be local. PIFR 2 clients won't pass the self test with core broken (which is why my sandbox client is in failed state in PIFR 2).
#24
We can try temporarily with #9, just skip the time window security layer, and then find a solution to the redirect issues.
#25
Ok, committed the patch in #9.
Restarting the testing bot again....
#26
Yay! I think it's back! :)
I had to disable slave #39, but the rest are coming back with passes. Turning reporting back on.
Thanks for all of your help folks!!!
#27
Automatically closed -- issue fixed for 2 weeks with no activity.
#28
f2_knight requested that failed test be re-tested.
#29
The last submitted patch failed testing.
#30
#31
Erm. Reopening that. We removed the time check instead of increasing it... (why?) thus strongly lowering the security of the system.
If we don't want a time check, we should clean-up the time variable from the token.
#32
We definitely need the Simpletest tokens to be non-replayable. This patch removed that without any consideration about the risks involved.
#33
indeed - this is really serious. Why was this committed?
#11 looks like it was trying to actually address the problem, not break our security model.
#34
Here's a roll-back patch for #9 accounting for core changes since then.
#35
#36
chx asks for a 30 second window (the default PHP timeout) until we fix the curl behavior, etc.
#37
looks good to me, we can adjust if the window is too small.
#38
It looks like #11 made it into core also? In that case, maybe we are ok with 2 seconds (or something shorter than 30)?
#39
+++ includes/bootstrap.inc@@ -2261,8 +2261,11 @@ function drupal_valid_test_ua($user_agent) {
+ // @todo - fix the curl redirect behavior so we can shorten this time window.
If I'd scan through bootstrap.inc and read this todo, I'd have no idea of what the author was trying to tell here.
Also, remove the leading hyphen and use proper capitalization/punctuation.
+++ includes/bootstrap.inc@@ -2261,8 +2261,11 @@ function drupal_valid_test_ua($user_agent) {
+ return (($time_diff >= 0) && ($time_diff <= 30) && $hmac == drupal_hmac_base64($check_string, $key));
Parentheses around inner conditions ($time_diff >= 0) are needless.
40 critical left. Go review some!
#40
in fact looks like that curl fix was already made, so let's try this with ~5 sec?
@sun - I find the parens are more readable (even if they are needless) - and they were in core before. Do we have a code style standard here?
#41
#42
+++ includes/bootstrap.inc@@ -2261,8 +2261,10 @@ function drupal_valid_test_ua($user_agent) {
+ return (($time_diff >= 0) && ($time_diff <= 5) && $hmac == drupal_hmac_base64($check_string, $key));
If it's really more readable, then why isn't the last condition wrapped in parentheses? :)
EDIT: on a second read, all additional parentheses are needless on this line.
return $time_diff >= 0 && $time_diff <= 5 && $hmac == drupal_hmac_base64($check_string, $key);Sorry, I can't RTBC, not familiar enough with this code.
#43
There seems to be no real standard on the use of parens - so I favor them if they add readability.
see:
http://api.drupal.org/api/function/drupal_valid_token/7
http://api.drupal.org/api/function/drupal_is_cli/7
http://api.drupal.org/api/function/drupal_page_is_cacheable/7
Given that this is essentially just rolling back a commit above , I think it's RTBC as long as the tests pass (which was the reason for this issue in any case).
#44
Really sorry. :( I remember being in a bit of a desperate state trying to get testbot back on at the time this was committed, and didn't fully take in the ramifications of this patch.
Committed to HEAD!
#45
Automatically closed -- issue fixed for 2 weeks with no activity.