VYPR
Moderate severityNVD Advisory· Published Aug 25, 2021· Updated Sep 17, 2024

Unauthorized property update in CheckboxGroup component in Vaadin 12-14 and 15-20

CVE-2021-33605

Description

Improper check in CheckboxGroup in com.vaadin:vaadin-checkbox-flow versions 1.2.0 prior to 2.0.0 (Vaadin 12.0.0 prior to 14.0.0), 2.0.0 prior to 3.0.0 (Vaadin 14.0.0 prior to 14.5.0), 3.0.0 through 4.0.1 (Vaadin 15.0.0 through 17.0.11), 14.5.0 through 14.6.7 (Vaadin 14.5.0 through 14.6.7), and 18.0.0 through 20.0.5 (Vaadin 18.0.0 through 20.0.5) allows attackers to modify the value of a disabled Checkbox inside enabled CheckboxGroup component via unspecified vectors.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.vaadin:vaadin-checkbox-flowMaven
>= 12.0.0, < 14.6.814.6.8
com.vaadin:vaadin-checkbox-flowMaven
>= 15.0.0, < 20.0.620.0.6

Affected products

2
  • Range: 12.0.0
  • Vaadin/vaadin-checkbox-flowv5
    Range: 1.2.0

Patches

2
1aa6bc94c763

fix: allow changing checkboxgroup value if disabled checkbox value doesn't change (#1903) (#1970)

https://github.com/vaadin/flow-componentsVaadin BotAug 3, 2021via ghsa
3 files changed · +66 7
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow-integration-tests/src/main/java/com/vaadin/flow/component/checkbox/tests/CheckboxGroupDisabledItemPage.java+15 1 modified
    @@ -1,6 +1,8 @@
     package com.vaadin.flow.component.checkbox.tests;
     
     import com.vaadin.flow.component.checkbox.CheckboxGroup;
    +import com.vaadin.flow.component.html.Div;
    +import com.vaadin.flow.component.html.NativeButton;
     import com.vaadin.flow.component.orderedlayout.VerticalLayout;
     import com.vaadin.flow.router.Route;
     
    @@ -18,6 +20,18 @@ public CheckboxGroupDisabledItemPage() {
             group.select("bar");
             group.setItemEnabledProvider(item -> !"bar".equals(item));
             group.setId("checkbox-group-disabled-item");
    -        add(group);
    +
    +        NativeButton toggleBarButton = new NativeButton("Toggle \"bar\"",
    +                event -> {
    +                    boolean isBarSelected = group.isSelected("bar");
    +                    if (isBarSelected) {
    +                        group.deselect("bar");
    +                    } else {
    +                        group.select("bar");
    +                    }
    +                });
    +        toggleBarButton.setId("toggle-bar-button");
    +
    +        add(group, new Div(toggleBarButton));
         }
     }
    
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow-integration-tests/src/test/java/com/vaadin/flow/component/checkbox/tests/CheckboxGroupDisabledItemIT.java+41 0 modified
    @@ -37,4 +37,45 @@ public void disabledGroupItemChecked() {
             Assert.assertEquals(Boolean.TRUE.toString(),
                     checkboxes.get(1).getAttribute("checked"));
         }
    +
    +    @Test
    +    public void disabledItemCanBeCheckedProgrammatically() {
    +        open();
    +        TestBenchElement group = $(TestBenchElement.class)
    +                .id("checkbox-group-disabled-item");
    +        List<TestBenchElement> checkboxes = group.$("vaadin-checkbox").all();
    +        TestBenchElement secondCheckbox = checkboxes.get(1);
    +        TestBenchElement toggleBarButton = $("button").id("toggle-bar-button");
    +
    +        // Deselect
    +        toggleBarButton.click();
    +        Assert.assertNull(secondCheckbox.getAttribute("checked"));
    +
    +        // Reselect
    +        toggleBarButton.click();
    +        Assert.assertEquals(Boolean.TRUE.toString(),
    +                secondCheckbox.getAttribute("checked"));
    +    }
    +
    +    /**
    +     * Regression test for:
    +     * https://github.com/vaadin/flow-components/issues/1185
    +     */
    +    @Test
    +    public void enabledItemCanBeCheckedManuallyWhenSettingItemEnabledProviderAfterSelectingValue() {
    +        open();
    +        TestBenchElement group = $(TestBenchElement.class)
    +                .id("checkbox-group-disabled-item");
    +        List<TestBenchElement> checkboxes = group.$("vaadin-checkbox").all();
    +        TestBenchElement firstCheckbox = checkboxes.get(0);
    +
    +        // Select
    +        firstCheckbox.click();
    +        Assert.assertEquals(Boolean.TRUE.toString(),
    +                firstCheckbox.getAttribute("checked"));
    +
    +        // Deselect
    +        firstCheckbox.click();
    +        Assert.assertNull(firstCheckbox.getAttribute("checked"));
    +    }
     }
    
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow/src/main/java/com/vaadin/flow/component/checkbox/CheckboxGroup.java+10 6 modified
    @@ -325,12 +325,16 @@ protected boolean valueEquals(Set<T> value1, Set<T> value2) {
     
         @Override
         protected boolean hasValidValue() {
    -        Set<T> selectedItems = presentationToModel(this,
    +        // we need to compare old value with new value to see if any disabled
    +        // items changed their value
    +        Set<T> value = presentationToModel(this,
                     (JsonArray) getElement().getPropertyRaw(VALUE));
    -        if (selectedItems == null || selectedItems.isEmpty()) {
    -            return true;
    -        }
    -        return selectedItems.stream().allMatch(itemEnabledProvider);
    +        Set<T> oldValue = getValue();
    +
    +        // disabled items cannot change their value
    +        return getCheckboxItems().filter(CheckBoxItem::isDisabledBoolean)
    +                .noneMatch(item -> oldValue.contains(item.getItem()) != value
    +                        .contains(item.getItem()));
         }
     
         private void reset() {
    @@ -401,7 +405,7 @@ private void validateSelectionEnabledState(PropertyChangeEvent event) {
                 } finally {
                     registerValidation();
                 }
    -            // Now make sure that the button is still in the correct state
    +            // Now make sure that the checkbox is still in the correct state
                 Set<T> value = presentationToModel(this,
                         (JsonArray) event.getValue());
                 getCheckboxItems()
    
f136532a735f

fix: allow changing checkboxgroup value if disabled checkbox value doesn't change (#1903) (#1968)

https://github.com/vaadin/flow-componentsVaadin BotAug 3, 2021via ghsa
3 files changed · +66 7
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow-integration-tests/src/main/java/com/vaadin/flow/component/checkbox/tests/CheckboxGroupDisabledItemPage.java+15 1 modified
    @@ -1,6 +1,8 @@
     package com.vaadin.flow.component.checkbox.tests;
     
     import com.vaadin.flow.component.checkbox.CheckboxGroup;
    +import com.vaadin.flow.component.html.Div;
    +import com.vaadin.flow.component.html.NativeButton;
     import com.vaadin.flow.component.orderedlayout.VerticalLayout;
     import com.vaadin.flow.router.Route;
     
    @@ -18,6 +20,18 @@ public CheckboxGroupDisabledItemPage() {
             group.select("bar");
             group.setItemEnabledProvider(item -> !"bar".equals(item));
             group.setId("checkbox-group-disabled-item");
    -        add(group);
    +
    +        NativeButton toggleBarButton = new NativeButton("Toggle \"bar\"",
    +                event -> {
    +                    boolean isBarSelected = group.isSelected("bar");
    +                    if (isBarSelected) {
    +                        group.deselect("bar");
    +                    } else {
    +                        group.select("bar");
    +                    }
    +                });
    +        toggleBarButton.setId("toggle-bar-button");
    +
    +        add(group, new Div(toggleBarButton));
         }
     }
    
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow-integration-tests/src/test/java/com/vaadin/flow/component/checkbox/tests/CheckboxGroupDisabledItemIT.java+41 0 modified
    @@ -37,4 +37,45 @@ public void disabledGroupItemChecked() {
             Assert.assertEquals(Boolean.TRUE.toString(),
                     checkboxes.get(1).getAttribute("checked"));
         }
    +
    +    @Test
    +    public void disabledItemCanBeCheckedProgrammatically() {
    +        open();
    +        TestBenchElement group = $(TestBenchElement.class)
    +                .id("checkbox-group-disabled-item");
    +        List<TestBenchElement> checkboxes = group.$("vaadin-checkbox").all();
    +        TestBenchElement secondCheckbox = checkboxes.get(1);
    +        TestBenchElement toggleBarButton = $("button").id("toggle-bar-button");
    +
    +        // Deselect
    +        toggleBarButton.click();
    +        Assert.assertNull(secondCheckbox.getAttribute("checked"));
    +
    +        // Reselect
    +        toggleBarButton.click();
    +        Assert.assertEquals(Boolean.TRUE.toString(),
    +                secondCheckbox.getAttribute("checked"));
    +    }
    +
    +    /**
    +     * Regression test for:
    +     * https://github.com/vaadin/flow-components/issues/1185
    +     */
    +    @Test
    +    public void enabledItemCanBeCheckedManuallyWhenSettingItemEnabledProviderAfterSelectingValue() {
    +        open();
    +        TestBenchElement group = $(TestBenchElement.class)
    +                .id("checkbox-group-disabled-item");
    +        List<TestBenchElement> checkboxes = group.$("vaadin-checkbox").all();
    +        TestBenchElement firstCheckbox = checkboxes.get(0);
    +
    +        // Select
    +        firstCheckbox.click();
    +        Assert.assertEquals(Boolean.TRUE.toString(),
    +                firstCheckbox.getAttribute("checked"));
    +
    +        // Deselect
    +        firstCheckbox.click();
    +        Assert.assertNull(firstCheckbox.getAttribute("checked"));
    +    }
     }
    
  • vaadin-checkbox-flow-parent/vaadin-checkbox-flow/src/main/java/com/vaadin/flow/component/checkbox/CheckboxGroup.java+10 6 modified
    @@ -442,12 +442,16 @@ protected boolean valueEquals(Set<T> value1, Set<T> value2) {
     
         @Override
         protected boolean hasValidValue() {
    -        Set<T> selectedItems = presentationToModel(this,
    +        // we need to compare old value with new value to see if any disabled
    +        // items changed their value
    +        Set<T> value = presentationToModel(this,
                     (JsonArray) getElement().getPropertyRaw(VALUE));
    -        if (selectedItems == null || selectedItems.isEmpty()) {
    -            return true;
    -        }
    -        return selectedItems.stream().allMatch(itemEnabledProvider);
    +        Set<T> oldValue = getValue();
    +
    +        // disabled items cannot change their value
    +        return getCheckboxItems().filter(CheckBoxItem::isDisabledBoolean)
    +                .noneMatch(item -> oldValue.contains(item.getItem()) != value
    +                        .contains(item.getItem()));
         }
     
         @SuppressWarnings("unchecked")
    @@ -540,7 +544,7 @@ private void validateSelectionEnabledState(PropertyChangeEvent event) {
                 } finally {
                     registerValidation();
                 }
    -            // Now make sure that the button is still in the correct state
    +            // Now make sure that the checkbox is still in the correct state
                 Set<T> value = presentationToModel(this,
                         (JsonArray) event.getValue());
                 getCheckboxItems()
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.