Apache OpenMeetings: allows null-byte Injection
Description
An attacker who has gained access to an admin account can perform RCE via null-byte injection
Vendor: The Apache Software Foundation
Versions Affected: Apache OpenMeetings from 2.0.0 before 7.1.0
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Admin account access allows RCE via null-byte injection in Apache OpenMeetings before 7.1.0.
Vulnerability
CVE-2023-29246 is a remote code execution (RCE) vulnerability in Apache OpenMeetings versions 2.0.0 through 7.0.0. An attacker who has already gained administrative access can exploit a null-byte injection flaw in the configuration settings to execute arbitrary commands on the server. The root cause is insufficient validation of path-type configuration values, allowing the injection of a null byte to bypass intended path checks [1][4].
Exploitation
The vulnerability is exploitable only after an attacker obtains admin-level privileges, which may be achieved through other means such as credential compromise or phishing. Once authenticated as an admin, the attacker can modify configuration keys such as CONFIG_PATH_FFMPEG or CONFIG_PATH_OFFICE by appending a null byte and arbitrary command payload. The input validation added in commit 9f12a48 explicitly checks for valid file paths and blocks null bytes, but prior versions lack this protection [3].
Impact
Successful exploitation allows the attacker to execute arbitrary code on the OpenMeetings server with the privileges of the application process. This can lead to full server compromise, data exfiltration, installation of backdoors, or further lateral movement within the network. The severity is high given the potential for complete system takeover, though the attack requires prior admin access [4].
Mitigation
Users should upgrade to Apache OpenMeetings 7.1.0 or later, which implements strict validation of path configuration entries as part of broader security hardening [1][2]. No workaround is provided for unpatched versions; upgrading is the only reliable fix.
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.openmeetings:openmeetings-parentMaven | >= 2.0.0, < 7.1.0 | 7.1.0 |
Affected products
2- Apache Software Foundation/Apache OpenMeetingsv5Range: 2.0.0
Patches
3f91ff1917027[OPENMEETINGS-2765] config creation is fixed
1 file changed · +4 −4
openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java+4 −4 modified@@ -251,12 +251,12 @@ public static List<Configuration> initialCfgs(InstallationConfig cfg) { addCfg(list, CONFIG_DOCUMENT_QUALITY, String.valueOf(cfg.getDocQuality()), Configuration.Type.NUMBER, "compression quality for conversion of PDF to images (should be an integer between 1 and 100, with a default value of 90)", VER_2_0); - addCfg(list, CONFIG_PATH_IMAGEMAGIC, cfg.getImageMagicPath(), Configuration.Type.STRING, "Path to ImageMagick tools", VER_2_0); + addCfg(list, CONFIG_PATH_IMAGEMAGIC, cfg.getImageMagicPath(), Configuration.Type.PATH, "Path to ImageMagick tools", VER_2_0); - addCfg(list, CONFIG_PATH_SOX, cfg.getSoxPath(), Configuration.Type.STRING, "Path To SoX-Tools", VER_2_0); + addCfg(list, CONFIG_PATH_SOX, cfg.getSoxPath(), Configuration.Type.PATH, "Path To SoX-Tools", VER_2_0); - addCfg(list, CONFIG_PATH_FFMPEG, cfg.getFfmpegPath(), Configuration.Type.STRING, "Path To FFMPEG", VER_2_0); - addCfg(list, CONFIG_PATH_OFFICE, cfg.getOfficePath(), Configuration.Type.STRING, + addCfg(list, CONFIG_PATH_FFMPEG, cfg.getFfmpegPath(), Configuration.Type.PATH, "Path To FFMPEG", VER_2_0); + addCfg(list, CONFIG_PATH_OFFICE, cfg.getOfficePath(), Configuration.Type.PATH, "The path to OpenOffice/LibreOffice (optional) please set this to the real path in case jodconverter is unable to find OpenOffice/LibreOffice installation automatically", VER_2_0); addCfg(list, CONFIG_DASHBOARD_RSS_FEED1, cfg.getUrlFeed(), Configuration.Type.STRING, "Feed URL 1", VER_1_9);
8e65a1344157[OPENMEETINGS-2765] paths are being validated
2 files changed · +6 −0
openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Configuration.java+1 −0 modified@@ -70,6 +70,7 @@ public enum Type { , NUMBER , BOOL , HOTKEY + , PATH } @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
openmeetings-install/src/main/java/org/apache/openmeetings/backup/BackupImport.java+5 −0 modified@@ -314,6 +314,11 @@ public class BackupImport { , entry(CONFIG_MIC_NOISE, Configuration.Type.BOOL) , entry(CONFIG_EXT_PROCESS_TTL, Configuration.Type.NUMBER) , entry(CONFIG_RECORDING_ENABLED, Configuration.Type.BOOL) + // ConfigForm.PATHS should also be updated + , entry(CONFIG_PATH_FFMPEG, Configuration.Type.PATH) + , entry(CONFIG_PATH_IMAGEMAGIC, Configuration.Type.PATH) + , entry(CONFIG_PATH_OFFICE, Configuration.Type.PATH) + , entry(CONFIG_PATH_SOX, Configuration.Type.PATH) ); private static final Pattern UUID_PATTERN = Pattern.compile("^[\\da-f]{8}(?:-[\\da-f]{4}){3}-[\\da-f]{12}$");
9f12a48994d0[OPENMEETINGS-2765] paths are being validated
2 files changed · +34 −3
openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/configurations/ConfigForm.java+33 −2 modified@@ -18,10 +18,17 @@ */ package org.apache.openmeetings.web.admin.configurations; +import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_PATH_FFMPEG; +import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_PATH_IMAGEMAGIC; +import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_PATH_OFFICE; +import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_PATH_SOX; import static org.apache.openmeetings.web.common.BasePanel.EVT_CHANGE; import static org.apache.wicket.validation.validator.StringValidator.maximumLength; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.util.List; +import java.util.Set; import org.apache.openmeetings.db.dao.basic.ConfigurationDao; import org.apache.openmeetings.db.entity.basic.Configuration; @@ -59,6 +66,7 @@ */ public class ConfigForm extends AdminBaseForm<Configuration> { private static final long serialVersionUID = 1L; + private static final Set<String> PATHS = Set.of(CONFIG_PATH_FFMPEG, CONFIG_PATH_IMAGEMAGIC, CONFIG_PATH_OFFICE, CONFIG_PATH_SOX); private final WebMarkupContainer listContainer; private final WebMarkupContainer stringBox = new WebMarkupContainer("string-box"); private final WebMarkupContainer numberBox = new WebMarkupContainer("number-box"); @@ -90,7 +98,7 @@ private void refresh(AjaxRequestTarget target) { private void update(AjaxRequestTarget target) { Configuration c = getModelObject(); - stringBox.setVisible(Type.STRING == c.getType()); + stringBox.setVisible(Type.PATH == c.getType() || Type.STRING == c.getType()); numberBox.setVisible(Type.NUMBER == c.getType()); booleanBox.setVisible(Type.BOOL == c.getType()); hotkeyBox.setVisible(Type.HOTKEY == c.getType()); @@ -151,6 +159,21 @@ public void validate(IValidatable<String> validatable) { } }).add(maximumLength(255))); valueS.add(maximumLength(255)); + valueS.add(new IValidator<String>(){ + private static final long serialVersionUID = 1L; + + @Override + public void validate(IValidatable<String> validatable) { + Configuration c = getModelFixType(); + if (Type.PATH == c.getType()) { + try { + Path.of(validatable.getValue()); + } catch (InvalidPathException e) { + validatable.error(new ValidationError(e.getMessage())); + } + } + } + }); stringBox.add(valueS.setLabel(new ResourceModel("271"))).setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true); numberBox.add(valueN.setLabel(new ResourceModel("271"))).setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true); booleanBox.add(valueB.setLabel(new ResourceModel("271"))).setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true); @@ -159,13 +182,21 @@ public void validate(IValidatable<String> validatable) { setNewRecordVisible(true); } + private Configuration getModelFixType() { + Configuration c = ConfigForm.this.getModelObject(); + if (c.getKey() != null && PATHS.contains(c.getKey())) { + c.setType(Type.PATH); + } + return c; + } + @Override protected void onSaveSubmit(AjaxRequestTarget target, Form<?> form) { Configuration c = cfgDao.forceGet(getModelObject().getKey()); if (c != null && c.isDeleted() && !c.getId().equals(getModelObject().getId())) { getModelObject().setId(c.getId()); } - setModelObject(cfgDao.update(getModelObject(), WebSession.getUserId())); + setModelObject(cfgDao.update(getModelFixType(), WebSession.getUserId())); setNewRecordVisible(false); target.add(listContainer); refresh(target);
openmeetings-web/src/main/java/org/apache/openmeetings/web/common/FormActionsPanel.java+1 −1 modified@@ -43,7 +43,7 @@ protected FormActionsPanel(String id, Form<T> form) { @Override protected void onInitialize() { - add(feedback.setOutputMarkupId(true)); + add(feedback.setOutputMarkupPlaceholderTag(true).setOutputMarkupId(true)); // add a save button that can be used to submit the form via ajax add(saveBtn = new AjaxButton("btn-save", form) {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-mg5h-f3q8-c96gghsaADVISORY
- lists.apache.org/thread/230plvhbdx26m43b0sy942wlwt6kkmmrghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2023-29246ghsaADVISORY
- github.com/apache/openmeetings/commit/8e65a1344157b2898f2922d49a0bd2105687c4a5ghsaWEB
- github.com/apache/openmeetings/commit/9f12a48994d0ad741ac140c52cbd2152f0d048d5ghsaWEB
- github.com/apache/openmeetings/commit/f91ff1917027625f066a9007694a31d06e69df3aghsaWEB
- issues.apache.org/jira/browse/OPENMEETINGS-2765ghsaWEB
News mentions
0No linked articles in our index yet.