VYPR
Medium severityGHSA Advisory· Published Sep 4, 2025· Updated Apr 15, 2026

CVE-2025-9467

CVE-2025-9467

Description

When the Vaadin Upload's start listener is used to validate metadata about an incoming upload, it is possible to bypass the upload validation.

Users of affected versions should apply the following mitigation or upgrade. Releases that have fixed this issue include:

Product version Vaadin 7.0.0 - 7.7.47 Vaadin 8.0.0 - 8.28.1 Vaadin 14.0.0 - 14.13.0 Vaadin 23.0.0 - 23.6.1 Vaadin 24.0.0 - 24.7.6

Mitigation Upgrade to 7.7.48 Upgrade to 8.28.2 Upgrade to 14.13.1 Upgrade to 23.6.2 Upgrade to 24.7.7 or newer

Please note that Vaadin versions 10-13 and 15-22 are no longer supported and you should update either to the latest 14, 23, 24 version.

Artifacts     Maven coordinatesVulnerable versionsFixed versioncom.vaadin:vaadin-server 7.0.0 - 7.7.47 ≥7.7.48 com.vaadin:vaadin-server 8.0.0 - 8.28.1 ≥8.28.2 com.vaadin:vaadin 14.0.0 - 14.13.0 ≥14.13.1 com.vaadin:vaadin23.0.0 - 23.6.1 ≥23.6.2 com.vaadin:vaadin24.0.0 - 24.7.6 ≥24.7.7com.vaadin:vaadin-upload-flow 2.0.0 - 14.13.0 ≥14.13.1 com.vaadin:vaadin-upload-flow 23.0.0 - 23.6.1 ≥23.6.2 com.vaadin:vaadin-upload-flow 24.0.0 - 24.7.6 ≥24.7.7

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
com.vaadin:vaadin-serverMaven
>= 7.0.0, < 7.7.487.7.48
com.vaadin:vaadin-serverMaven
>= 8.0.0, < 8.28.28.28.2

Affected products

1

Patches

1
bfe9e507cdcc

fix: interrupt all uploads (#7616)

https://github.com/vaadin/flow-componentsSascha IßbrückerJun 18, 2025via ghsa
3 files changed · +161 3
  • vaadin-upload-flow-parent/vaadin-upload-flow-integration-tests/src/main/java/com/vaadin/flow/component/upload/tests/UploadInterruptView.java+93 0 added
    @@ -0,0 +1,93 @@
    +/*
    + * Copyright 2000-2025 Vaadin Ltd.
    + *
    + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
    + * use this file except in compliance with the License. You may obtain a copy of
    + * the License at
    + *
    + * http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    + * License for the specific language governing permissions and limitations under
    + * the License.
    + */
    +package com.vaadin.flow.component.upload.tests;
    +
    +import java.io.FilterOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +
    +import com.vaadin.flow.component.html.Div;
    +import com.vaadin.flow.component.upload.Upload;
    +import com.vaadin.flow.component.upload.receivers.MultiFileMemoryBuffer;
    +import com.vaadin.flow.router.Route;
    +
    +@Route("vaadin-upload/interrupt")
    +public class UploadInterruptView extends Div {
    +
    +    public UploadInterruptView() {
    +        Div output = new Div();
    +        output.setId("test-output");
    +        Div eventsOutput = new Div();
    +        eventsOutput.setId("test-events-output");
    +
    +        MultiFileMemoryBuffer buffer = new SlowMultiFileMemoryBuffer();
    +        Upload upload = new Upload(buffer);
    +        upload.setAcceptedFileTypes(".txt");
    +        upload.addStartedListener(event -> {
    +            if (isInterruptableFile(event.getFileName())) {
    +                event.getUpload().interruptUpload();
    +            }
    +        });
    +        upload.addFailedListener(event -> {
    +            eventsOutput.add("-failed");
    +            output.add("FAILED:" + event.getFileName() + ","
    +                    + event.getReason().getMessage());
    +        });
    +        upload.addSucceededListener(event -> eventsOutput.add("-succeeded"));
    +        upload.addAllFinishedListener(event -> eventsOutput.add("-finished"));
    +
    +        add(upload, output, eventsOutput);
    +    }
    +
    +    private static boolean isInterruptableFile(String fileName) {
    +        return fileName != null && fileName.endsWith(".interrupt.txt");
    +    }
    +
    +    // Returns an OutputStream that delays write operations for uploads. The
    +    // delay ensures that the interruption flag is set before uploads completion
    +    // so that the test can verify all uploads failed.
    +    private static class SlowMultiFileMemoryBuffer
    +            extends MultiFileMemoryBuffer {
    +        @Override
    +        public OutputStream receiveUpload(String fileName, String MIMEType) {
    +            OutputStream outputStream = super.receiveUpload(fileName, MIMEType);
    +            // Also delay the interrupted file to allow other uploads to start
    +            int delay = isInterruptableFile(fileName) ? 500 : 1000;
    +            return new SlowOutputStream(outputStream, delay);
    +        }
    +    }
    +
    +    private static class SlowOutputStream extends FilterOutputStream {
    +
    +        private final int delay;
    +
    +        SlowOutputStream(OutputStream delegate, int delay) {
    +            super(delegate);
    +            this.delay = delay;
    +        }
    +
    +        @Override
    +        public void write(byte[] b, int off, int len) throws IOException {
    +            try {
    +                Thread.sleep(delay);
    +            } catch (InterruptedException e) {
    +                Thread.currentThread().interrupt();
    +                throw new IOException("Interrupted", e);
    +            }
    +            super.write(b, off, len);
    +        }
    +    }
    +}
    
  • vaadin-upload-flow-parent/vaadin-upload-flow-integration-tests/src/test/java/com/vaadin/flow/component/upload/tests/UploadInterruptIT.java+63 0 added
    @@ -0,0 +1,63 @@
    +/*
    + * Copyright 2000-2025 Vaadin Ltd.
    + *
    + * Licensed under the Apache License, Version 2.0 (the "License"); you may not
    + * use this file except in compliance with the License. You may obtain a copy of
    + * the License at
    + *
    + * http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    + * License for the specific language governing permissions and limitations under
    + * the License.
    + */
    +package com.vaadin.flow.component.upload.tests;
    +
    +import java.io.File;
    +import java.util.List;
    +
    +import org.junit.Assert;
    +import org.junit.Before;
    +import org.junit.Test;
    +import org.openqa.selenium.WebElement;
    +
    +import com.vaadin.flow.component.upload.testbench.UploadElement;
    +import com.vaadin.flow.testutil.TestPath;
    +
    +@TestPath("vaadin-upload/interrupt")
    +public class UploadInterruptIT extends AbstractUploadIT {
    +
    +    private UploadElement upload;
    +    private WebElement uploadOutput;
    +    private WebElement eventsOutput;
    +
    +    @Before
    +    public void init() {
    +        open();
    +        upload = $(UploadElement.class).waitForFirst();
    +        uploadOutput = $("div").id("test-output");
    +        eventsOutput = $("div").id("test-events-output");
    +    }
    +
    +    @Test
    +    public void uploadMultipleFiles_interruptUpload_allOngoingUploadsInterrupted()
    +            throws Exception {
    +
    +        List<File> files = List.of(createTempFile("txt"), createTempFile("txt"),
    +                createTempFile("interrupt.txt"), createTempFile("txt"),
    +                createTempFile("txt"));
    +
    +        upload.uploadMultiple(files, 10);
    +
    +        Assert.assertEquals("Expected all uploads to be interrupted",
    +                "-failed-failed-failed-failed-failed-finished",
    +                eventsOutput.getText());
    +
    +        files.forEach(file -> Assert.assertTrue(
    +                "Expected upload of " + file.getName() + " to be failed",
    +                uploadOutput.getText().contains(
    +                        "FAILED:" + file.getName() + ",Upload interrupted")));
    +    }
    +}
    
  • vaadin-upload-flow-parent/vaadin-upload-flow/src/main/java/com/vaadin/flow/component/upload/Upload.java+5 3 modified
    @@ -80,7 +80,7 @@ public UploadIcon() {
         }
     
         private StreamVariable streamVariable;
    -    private boolean interrupted = false;
    +    private volatile boolean interrupted = false;
     
         private int activeUploads = 0;
         private boolean uploading;
    @@ -458,7 +458,7 @@ private void startUpload() {
          * The interruption will be done by the receiving thread so this method will
          * return immediately and the actual interrupt will happen a bit later.
          * <p>
    -     * Note! this will interrupt all uploads in multi-upload mode.
    +     * Note! this will interrupt all ongoing uploads in multi-upload mode.
          */
         public void interruptUpload() {
             if (isUploading()) {
    @@ -468,7 +468,9 @@ public void interruptUpload() {
     
         private void endUpload() {
             activeUploads--;
    -        interrupted = false;
    +        if (activeUploads == 0) {
    +            interrupted = false;
    +        }
         }
     
         /**
    

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

6

News mentions

0

No linked articles in our index yet.