import Oracle_OSS xmlrpc-c-1.51.0-17.el9_8
This commit is contained in:
parent
204a1aca57
commit
3c6afbe199
@ -0,0 +1,285 @@
|
||||
From d96aa99815b26058353964fd2c72145a9e748c51 Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
Date: Fri, 14 Aug 2026 08:42:22 +0200
|
||||
Subject: [PATCH] Fix HTML injection in Abyss error responses and directory
|
||||
listings
|
||||
|
||||
Backport of upstream SVN r3342. User-supplied URIs and filenames were
|
||||
inserted unescaped into HTML documents generated by the Abyss server
|
||||
(error pages and directory listings), allowing reflected XSS via
|
||||
crafted request URIs or filenames containing HTML control characters.
|
||||
|
||||
Add html_escapedForHtml() to replace &, <, >, ", ' with their HTML
|
||||
entity equivalents before embedding user-derived strings in HTML output.
|
||||
|
||||
Resolves: CVE-2026-15928
|
||||
|
||||
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
---
|
||||
lib/abyss/src/Makefile | 1 +
|
||||
lib/abyss/src/handler.c | 42 +++++++++++++++++--
|
||||
lib/abyss/src/html.c | 87 +++++++++++++++++++++++++++++++++++++++
|
||||
lib/abyss/src/html.h | 7 ++++
|
||||
lib/abyss/src/meson.build | 1 +
|
||||
lib/abyss/src/response.c | 15 ++++---
|
||||
6 files changed, 144 insertions(+), 9 deletions(-)
|
||||
create mode 100644 lib/abyss/src/html.c
|
||||
create mode 100644 lib/abyss/src/html.h
|
||||
|
||||
diff --git a/lib/abyss/src/Makefile b/lib/abyss/src/Makefile
|
||||
index 86f2552..133bf61 100644
|
||||
--- a/lib/abyss/src/Makefile
|
||||
+++ b/lib/abyss/src/Makefile
|
||||
@@ -45,6 +45,7 @@ TARGET_MODS = \
|
||||
date \
|
||||
file \
|
||||
handler \
|
||||
+ html \
|
||||
http \
|
||||
init \
|
||||
response \
|
||||
diff --git a/lib/abyss/src/handler.c b/lib/abyss/src/handler.c
|
||||
index 80a2914..98431eb 100644
|
||||
--- a/lib/abyss/src/handler.c
|
||||
+++ b/lib/abyss/src/handler.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "file.h"
|
||||
#include "conn.h"
|
||||
#include "http.h"
|
||||
+#include "html.h"
|
||||
#include "date.h"
|
||||
#include "abyss_info.h"
|
||||
|
||||
@@ -291,11 +292,15 @@ sendDirectoryDocumentHeading(TSession * const sessionP,
|
||||
"------------------------------------"
|
||||
"--------------------------------------------\r\n");
|
||||
} else {
|
||||
+ const char * const escapedUri = html_escapedForHtml(uri);
|
||||
+
|
||||
sprintf(z, "<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>"
|
||||
"<H1>Index of %s</H1><PRE>",
|
||||
- uri, uri);
|
||||
+ escapedUri, escapedUri);
|
||||
strcat(z, "Name Size "
|
||||
"Date-Time Type<HR WIDTH=100%>\r\n");
|
||||
+
|
||||
+ xmlrpc_strfree(escapedUri);
|
||||
}
|
||||
|
||||
HTTPWriteBodyChunk(sessionP, z, strlen(z));
|
||||
@@ -303,6 +308,37 @@ sendDirectoryDocumentHeading(TSession * const sessionP,
|
||||
|
||||
|
||||
|
||||
+static void
|
||||
+formatHtmlForDirEntry(char * const buffer,
|
||||
+ const char * const name,
|
||||
+ int const attrib,
|
||||
+ const char * const z1,
|
||||
+ const char * const z2,
|
||||
+ const char * const z3,
|
||||
+ const char * const z4,
|
||||
+ const char * const p) {
|
||||
+
|
||||
+ const char * const escapedName = html_escapedForHtml(name);
|
||||
+ const char * const escapedZ1 = html_escapedForHtml(z1);
|
||||
+ const char * const escapedZ2 = html_escapedForHtml(z2);
|
||||
+ const char * const escapedZ3 = html_escapedForHtml(z3);
|
||||
+ const char * const escapedZ4 = html_escapedForHtml(z4);
|
||||
+ const char * const escapedP = html_escapedForHtml(p);
|
||||
+
|
||||
+ sprintf(buffer, "<A HREF=\"%s%s\">%s</A>%s %s %s %s\r\n",
|
||||
+ escapedName, attrib & A_SUBDIR ? "/" : "",
|
||||
+ escapedZ1, escapedP, escapedZ3, escapedZ2, escapedZ4);
|
||||
+
|
||||
+ xmlrpc_strfree(escapedP);
|
||||
+ xmlrpc_strfree(escapedZ1);
|
||||
+ xmlrpc_strfree(escapedZ2);
|
||||
+ xmlrpc_strfree(escapedZ3);
|
||||
+ xmlrpc_strfree(escapedZ4);
|
||||
+ xmlrpc_strfree(escapedName);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
static void
|
||||
sendDirectoryDocument(TList * const listP,
|
||||
bool const ascending,
|
||||
@@ -405,9 +441,7 @@ sendDirectoryDocument(TList * const listP,
|
||||
if (text)
|
||||
sprintf(z, "%s%s %s %s %s\r\n", z1, p, z3, z2, z4);
|
||||
else
|
||||
- sprintf(z, "<A HREF=\"%s%s\">%s</A>%s %s %s %s\r\n",
|
||||
- fi->name, fi->attrib & A_SUBDIR ? "/" : "",
|
||||
- z1, p, z3, z2, z4);
|
||||
+ formatHtmlForDirEntry(z, fi->name, fi->attrib, z1, z2, z3, z4, p);
|
||||
|
||||
HTTPWriteBodyChunk(sessionP, z, strlen(z));
|
||||
}
|
||||
diff --git a/lib/abyss/src/html.c b/lib/abyss/src/html.c
|
||||
new file mode 100644
|
||||
index 0000000..eeb8b60
|
||||
--- /dev/null
|
||||
+++ b/lib/abyss/src/html.c
|
||||
@@ -0,0 +1,87 @@
|
||||
+/*=============================================================================
|
||||
+ html
|
||||
+===============================================================================
|
||||
+ This module contains utilities for processing HTML.
|
||||
+=============================================================================*/
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include <xmlrpc-c/string_int.h>
|
||||
+
|
||||
+#include "html.h"
|
||||
+
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+insertCharEntity(char * const buffer,
|
||||
+ unsigned int * const cursorP,
|
||||
+ const char * const name) {
|
||||
+
|
||||
+ size_t i;
|
||||
+
|
||||
+ buffer[(*cursorP)++] = '&';
|
||||
+
|
||||
+ for (i = 0; i < strlen(name); ++i)
|
||||
+ buffer[(*cursorP)++] = name[i];
|
||||
+
|
||||
+ buffer[(*cursorP)++] = ';';
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+const char *
|
||||
+html_escapedForHtml(const char * const plainText) {
|
||||
+/*----------------------------------------------------------------------------
|
||||
+ The text 'plainText' with HTML control characters replaced with
|
||||
+ HTML character entities so that the result can be used inside an HTML
|
||||
+ document without any chance of interfering with HTML controls.
|
||||
+
|
||||
+ In particular, we substitute one of the following for each associated
|
||||
+ character:
|
||||
+
|
||||
+ &
|
||||
+ <
|
||||
+ >
|
||||
+ "
|
||||
+ '
|
||||
+
|
||||
+ We return newly malloced storage or a constant if we can't get allocate
|
||||
+ enough, like 'xmlrpc_strdupsol', which must be freed with 'xmlrpc_strfree'.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
+
|
||||
+ size_t const maxPossibleReturnSz = strlen(plainText) * 6 + 1;
|
||||
+
|
||||
+ const char * retval;
|
||||
+ char * buffer; /* malloc'ed */
|
||||
+
|
||||
+ buffer = malloc(maxPossibleReturnSz);
|
||||
+
|
||||
+ if (!buffer)
|
||||
+ retval = xmlrpc_strnomemval();
|
||||
+ else {
|
||||
+ unsigned int inCursor, outCursor;
|
||||
+
|
||||
+ for (inCursor = 0, outCursor = 0;
|
||||
+ inCursor < strlen(plainText);
|
||||
+ ++inCursor) {
|
||||
+
|
||||
+ switch (plainText[inCursor]) {
|
||||
+ case '&': insertCharEntity(buffer, &outCursor, "amp"); break;
|
||||
+ case '<': insertCharEntity(buffer, &outCursor, "lt"); break;
|
||||
+ case '>': insertCharEntity(buffer, &outCursor, "gt"); break;
|
||||
+ case '"': insertCharEntity(buffer, &outCursor, "quot"); break;
|
||||
+ case '\'': insertCharEntity(buffer, &outCursor, "apos"); break;
|
||||
+ default:
|
||||
+ buffer[outCursor++] = plainText[inCursor];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ buffer[outCursor++] = '\0'; /* string-terminating NUL */
|
||||
+
|
||||
+ assert(outCursor <= maxPossibleReturnSz);
|
||||
+
|
||||
+ retval = buffer;
|
||||
+ }
|
||||
+ return retval;
|
||||
+}
|
||||
diff --git a/lib/abyss/src/html.h b/lib/abyss/src/html.h
|
||||
new file mode 100644
|
||||
index 0000000..97235f6
|
||||
--- /dev/null
|
||||
+++ b/lib/abyss/src/html.h
|
||||
@@ -0,0 +1,7 @@
|
||||
+#ifndef HTML_H_INCLUDED
|
||||
+#define HTML_H_INCLUDED
|
||||
+
|
||||
+const char *
|
||||
+html_escapedForHtml(const char * const plainText);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/lib/abyss/src/meson.build b/lib/abyss/src/meson.build
|
||||
index daa91fc..73c94d9 100644
|
||||
--- a/lib/abyss/src/meson.build
|
||||
+++ b/lib/abyss/src/meson.build
|
||||
@@ -30,6 +30,7 @@ libxmlrpc_abyss = library(
|
||||
'date.c',
|
||||
'file.c',
|
||||
'handler.c',
|
||||
+ 'html.c',
|
||||
'http.c',
|
||||
'init.c',
|
||||
'response.c',
|
||||
diff --git a/lib/abyss/src/response.c b/lib/abyss/src/response.c
|
||||
index cc0980a..7024d32 100644
|
||||
--- a/lib/abyss/src/response.c
|
||||
+++ b/lib/abyss/src/response.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "data.h"
|
||||
#include "abyss_info.h"
|
||||
#include "http.h"
|
||||
+#include "html.h"
|
||||
|
||||
|
||||
|
||||
@@ -41,24 +42,28 @@ void
|
||||
ResponseError2(TSession * const sessionP,
|
||||
const char * const explanation) {
|
||||
|
||||
+ const char * const escapedExplanation = html_escapedForHtml(explanation);
|
||||
+
|
||||
const char * errorDocument;
|
||||
|
||||
ResponseAddField(sessionP, "Content-type", "text/html");
|
||||
|
||||
ResponseWriteStart(sessionP);
|
||||
-
|
||||
+
|
||||
xmlrpc_asprintf(&errorDocument,
|
||||
"<HTML><HEAD><TITLE>Error %d</TITLE></HEAD>"
|
||||
"<BODY>"
|
||||
"<H1>Error %d</H1>"
|
||||
- "<P>%s</P>" SERVER_HTML_INFO
|
||||
+ "<P>%s</P>" SERVER_HTML_INFO
|
||||
"</BODY>"
|
||||
"</HTML>",
|
||||
- sessionP->status, sessionP->status, explanation);
|
||||
-
|
||||
- ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument));
|
||||
+ sessionP->status, sessionP->status, escapedExplanation);
|
||||
+
|
||||
+ ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument));
|
||||
|
||||
xmlrpc_strfree(errorDocument);
|
||||
+
|
||||
+ xmlrpc_strfree(escapedExplanation);
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.55.0
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
Name: xmlrpc-c
|
||||
Version: 1.51.0
|
||||
Release: 16%{?dist}
|
||||
Release: 17%{?dist}
|
||||
Summary: Lightweight RPC library based on XML and HTTP
|
||||
# See doc/COPYING for details.
|
||||
# The Python 1.5.2 license used by a few files is just BSD.
|
||||
@ -35,6 +35,8 @@ Patch201: 0001-Remove-trace-statements-accidentally-committed-with-.patch
|
||||
Patch1001: 0001-add-meson-buildsystem-definitions.patch
|
||||
Patch1002: 0002-chmod-x-xml-rpc-api2txt.patch
|
||||
|
||||
Patch1010: 1010-Fix-HTML-injection-in-Abyss-error-responses-and-dire.patch
|
||||
|
||||
BuildRequires: git-core
|
||||
BuildRequires: meson >= 0.36.0
|
||||
BuildRequires: gcc
|
||||
@ -197,9 +199,12 @@ rm -Rf lib/expat
|
||||
%{_bindir}/xmlrpc_dumpserver
|
||||
|
||||
%changelog
|
||||
* Fri Aug 14 2026 Michal Srb <michal@redhat.com> - 1.51.0-17
|
||||
- Fix HTML injection in Abyss error responses and directory listings
|
||||
- Resolves: CVE-2026-15928
|
||||
|
||||
* Thu Mar 17 2022 Michal Srb <michal@redhat.com> - 1.51.0-16
|
||||
- Drop bundled expat and build against libxml2
|
||||
- Resolves: CVE-2022-25235
|
||||
- Resolves: CVE-2022-25236
|
||||
|
||||
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.51.0-15
|
||||
|
||||
Loading…
Reference in New Issue
Block a user