Select box and radio button selection have protection against forgery of value of input selection. However for checkboxes, the form still submits the fake value of checkbox selection, which expected to be failed in validation and should return a message:
"An illegal choice has been detected. Please contact the site administrator."
Same with disabled input elements, making the "#disabled" property of any element to TRUE should prohibit the user from submitting the form but by editing the HTML code to remove the disabled="disabled" property of any input element and submit this form, Drupal does not validate this kind of forgery and still accept the submitted disabled input form.
I'm using D7 CVS updated.
Comment | File | Size | Author |
---|---|---|---|
#20 | checkboxes_forgery_fix-803212-21.patch | 4.14 KB | Heine |
#12 | issue.zip | 835 bytes | arpeggio |
#9 | checkboxes_forgery_fix-803212-9.patch | 4.18 KB | effulgentsia |
#8 | checkboxes_forgery_fix-803212-8.patch | 3.45 KB | effulgentsia |
Comments
Comment #1
arpeggio CreditAttribution: arpeggio commentedThis is a security issue, I think this is critical.
Comment #2
Heine CreditAttribution: Heine commentedTo reproduce:
When checking the checkboxes, results in (only relevant key given):
Whe modifying the value of $_POSTed secissue[two] to FOO:
Only the value is affected; when you try to add another key, the "Illegal option" error message is given. This is not an issue on Drupal 6.
Comment #3
Heine CreditAttribution: Heine commentedSee #426056: Server-side enforcement of #disabled is inconsistent for more info about #disabled.
Comment #4
arpeggio CreditAttribution: arpeggio commentedThank you for providing how to reproduce the issue. BTW, yesterday I've already sent the full details to security@drupal.org about this issue because Nathaniel suggested me that'll help you to track this. Thanks.
Comment #5
arpeggio CreditAttribution: arpeggio commentedI would like to suggest the following patch (for includes/form.inc) to solve the checkboxes input selection value forgery issue:
I removed the array_keys() because the suspected fake value/s is/are not in the array key/s but in the array value/s. Thanks.
Comment #6
Heine CreditAttribution: Heine commentedI've traced this back to #414424: Introduce Form API #type 'text_format'.
In Drupal 6, checkboxes behaviour results in:
regardless of the 'value' posted for the element.
What happens in D6 is that the "input" from the checkboxes element is added to form_state, and later overwritten by the child checkboxes; they always return the correct return_value. The following check that was added by the referenced issue prevents this overwriting by the child elements:
This _could_ be handled by the checkboxes value callback, or process handler, but I doubt that it is the correct approach; the behaviour of the processed element should depend on the children, and should not be coded entirely in the parent process / value callbacks.
Comment #7
Heine CreditAttribution: Heine commentedRelated issue #335035: drupalPost() incorrectly submits input for disabled elements.
Comment #8
effulgentsia CreditAttribution: effulgentsia commentedThanks. This fixes form_type_checkboxes_value() to be consistent with form_type_select_value().
Comment #9
effulgentsia CreditAttribution: effulgentsia commentedThis also fixes drupal_map_assoc() to handle empty arrays.
Comment #10
rfaysubscribe
Comment #11
effulgentsia CreditAttribution: effulgentsia commented@arpeggio: In the original issue description, you write:
This is true for D6, but was fixed for D7: #426056: Server-side enforcement of #disabled is inconsistent. If you can find a use-case where that bug remains, please post the steps to reproduce it. Thanks. Note, for D6, since #disabled isn't enforced server-side, if your module needs such enforcement, you need to set #value. See the linked issue.
Comment #12
arpeggio CreditAttribution: arpeggio commentedActually I have sent the detailed steps to security@drupal.org. Anyway here are the steps I sent and the attachment is the module I created:
Comment #13
Heine CreditAttribution: Heine commentedCan we please discuss the disabled issue elsewhere? edit; Maybe reopen #426056: Server-side enforcement of #disabled is inconsistent ?
Comment #14
Heine CreditAttribution: Heine commentedAs of #9; I find it odd that an element type processed into simpler types has no access to values of that type, but has to reimplement such functionality on raw $_POST data.
I would expect the following flow of information:
- type checkboxes -> processed into multiple checkbox elements
- value of all checkbox elements is set _individually_ in form_type_checkbox_value
- form_type_checkboxes_value runs later & receives these values, then returns the appropriate value for the checkboxes element.
- this value lands in form_state['values']
Unfortunately, it seems to late to do this in D7.
Comment #15
arpeggio CreditAttribution: arpeggio commented@Heine: I reopened your suggested thread about disabled issue.
Comment #16
effulgentsia CreditAttribution: effulgentsia commentedThanks for #12. #736298: Refactor file.module to use proper button click detection, enabling FAPI to improve button click detection security fixes that problem (see comment #46 on that issue): I'll try to roll in a test into that issue's patch with your use-case. So as per #13, this issue is now strictly about checkbox value forgery.
Re #14:
I agree that it is too late for that for D7. _form_builder_handle_input_element() runs in pre-order traversal (i.e., form_builder() calls it before recursing). This has been the case since FAPI was first introduced, and changing it to post-order traversal will have many side effects that are way out of scope for D7.
Comment #17
moshe weitzman CreditAttribution: moshe weitzman commentedanyone available to slay this critical?
Comment #18
effulgentsia CreditAttribution: effulgentsia commented#9 slays this as far as I'm concerned. Comments after it have been answered or relegated to other issues. Anyone available to RTBC this issue?
Comment #19
catchPatch is only a couple of lines and the test looks good, it would be nice to see another FAPI maintainer or Heine take a look at this before commit, maybe marking RTBC will encourage that second look.
Comment #20
Heine CreditAttribution: Heine commentedPatch itself is RTBC would it not for the options checker allowing the insertion of 0 keys:
Comment #21
effulgentsia CreditAttribution: effulgentsia commentedI think I agree with the change in #20, but I'm not sure it belongs in this issue. #654796: Identify fix bugs with checkbox element is still a critical issue for D7, and if the line in #20 has unwanted side-effects, that would be the issue to catch it. @Heine: what's your thinking for including it here?
Comment #22
Dries CreditAttribution: Dries commentedI reviewed this patch -- it fixes the problem. Committed to CVS HEAD. Thanks Heine and effulgentsia -- great job.
Comment #23
David_Rothstein CreditAttribution: David_Rothstein commentedThe change introduced in #20 did indeed have an unwanted side effect: It prevents drupal_form_submit() from programmatically turning off a checkbox by submitting a NULL value for it.
I posted a patch which fixes it here (not a simple rollback, since for everything but checkboxes I think #20 is probably correct):
#827430: drupal_form_submit() no longer works with checkboxes
It could be pulled into #654796: Identify fix bugs with checkbox element instead, but I think probably not, since this really is just about NULL values rather than other things which also evaluate to empty.