From 387cc40f84368e736fa043115bc2aacac515be41 Mon Sep 17 00:00:00 2001
From: NickSdot
Date: Sun, 19 Jul 2026 23:04:21 +0700
Subject: [PATCH 1/2] Canonicalise feed base URL handling
---
group.php | 19 ++++++++++++-------
lib/config.php | 7 +++++++
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/group.php b/group.php
index 4884b1c..005941e 100644
--- a/group.php
+++ b/group.php
@@ -29,15 +29,18 @@
error($e->getMessage());
}
-$host = htmlspecialchars($_SERVER['HTTP_HOST'], ENT_QUOTES, "UTF-8");
+$cleanBaseUrl = clean($NEWS_WEB_BASE_URL);
+$baseUrlParts = parse_url($NEWS_WEB_BASE_URL);
+$cleanBaseHost = clean($baseUrlParts['host'] . (isset($baseUrlParts['port']) ? ':' . $baseUrlParts['port'] : ''));
+$cleanGroupUrl = urlencode($group);
switch ($format) {
case 'rss':
header("Content-type: text/xml");
echo '' . "\n";?>
- :
- http:///group.php?group=
+ :
+ /group.php?group=
- :
- http:///group.php?group=
+ :
+ /group.php?group=
Newsgroup at
en-US
@@ -146,11 +149,13 @@
foreach ($overview['articles'] as $articleNumber => $details) {
/* $date = date("H:i:s M/d/y", strtotime($odate)); */
$date822 = date("r", strtotime($details['date']));
+ $cleanArticlePath = "/$cleanGroupUrl/" . urlencode((string) $articleNumber);
+ $cleanArticleLink = "$cleanBaseUrl$cleanArticlePath";
switch ($format) {
case 'rss':
echo " - \n";
- echo " http://$host/$group/$articleNumber\n";
+ echo " $cleanArticleLink\n";
echo " ", format_subject($details['subject'], $charset), "\n";
echo " ",
htmlspecialchars(format_author($details['author'], $charset), ENT_QUOTES, "UTF-8"),
@@ -161,7 +166,7 @@
case 'rdf':
echo "
- \n";
echo " ", format_subject($details['subject'], $charset), "\n";
- echo " http://$host/$group/$articleNumber\n";
+ echo " $cleanArticleLink\n";
echo " ",
htmlspecialchars(format_author($details['author'], $charset), ENT_QUOTES, "UTF-8"),
"\n";
diff --git a/lib/config.php b/lib/config.php
index 71a3835..dc80df9 100644
--- a/lib/config.php
+++ b/lib/config.php
@@ -4,3 +4,10 @@
if (getenv('NNTP_HOST')) {
$NNTP_HOST = getenv('NNTP_HOST');
}
+
+$NEWS_WEB_BASE_URL = 'https://news.php.net';
+if (getenv('NEWS_WEB_BASE_URL')) {
+ $NEWS_WEB_BASE_URL = rtrim(getenv('NEWS_WEB_BASE_URL'), '/');
+} elseif (PHP_SAPI == 'cli-server') {
+ $NEWS_WEB_BASE_URL = 'http://' . $_SERVER['HTTP_HOST'];
+}
From 4227758b3ce4d2ff3117cab354f061a8ebe77272 Mon Sep 17 00:00:00 2001
From: NickSdot
Date: Sun, 19 Jul 2026 23:07:24 +0700
Subject: [PATCH 2/2] Apply additional output hardening
---
article.php | 26 ++++++++++++++------------
group.php | 25 +++++++++++++------------
index.php | 11 ++++++-----
lib/ThreadTree.php | 7 ++++---
lib/common.php | 21 +++++++++++++--------
lib/group-navbar.php | 6 +++---
6 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/article.php b/article.php
index 7db4dbd..a9d5760 100644
--- a/article.php
+++ b/article.php
@@ -60,14 +60,17 @@
}
head("{$group}: " . format_title($mail['headers']['subject'], 'utf-8'));
+$cleanGroupUrl = urlencode($group);
+$cleanGroup = clean($group);
+
echo '';
@@ -107,7 +110,7 @@
echo ' \n";
}
@@ -331,7 +334,7 @@
$name = $attachment['filename'];
if ($mimetype == 'text/plain') {
- echo htmlspecialchars($attachment['data']);
+ echo clean($attachment['data']);
continue;
}
@@ -347,14 +350,14 @@
$link_desc .= " " . $description;
}
- $dl_link = "/getpart.php?group=$group&article=$article&part=$mimecount";
- $link_desc = htmlspecialchars($link_desc, ENT_QUOTES, 'UTF-8');
+ $dl_link = "/getpart.php?group=" . urlencode($group) . "&article=" . urlencode((string) $article) . "&part=" . urlencode((string) $mimecount);
+ $link_desc = clean($link_desc);
/* Attachment filename and mimetype might contain malicious characters */
printf(
'Attachment: %s
' . "\n",
$dl_link,
- htmlspecialchars($link_desc)
+ $link_desc,
);
}
}
@@ -380,7 +383,6 @@
// Does not check existence of next, so consider this the super duper fast [broken] version
// Based off navbar() in group.php
-$group = htmlspecialchars($group, ENT_QUOTES, "UTF-8");
$current = $article;
echo ' ' . "\n";
@@ -388,15 +390,15 @@
echo ' | ';
if ($current > 1) {
- echo ' « previous';
+ echo ' « previous';
} else {
echo ' ';
}
echo ' | ' . "\n";
-echo ' ' . "$group (#$current) | \n";
+echo ' ' . $cleanGroup . " (#$current) | \n";
echo ' ';
-echo ' next »';
+echo ' next »';
echo ' | ' . "\n";
echo ' ' . "\n";
echo '
' . "\n";
diff --git a/group.php b/group.php
index 005941e..fee98b1 100644
--- a/group.php
+++ b/group.php
@@ -33,13 +33,14 @@
$baseUrlParts = parse_url($NEWS_WEB_BASE_URL);
$cleanBaseHost = clean($baseUrlParts['host'] . (isset($baseUrlParts['port']) ? ':' . $baseUrlParts['port'] : ''));
$cleanGroupUrl = urlencode($group);
+$cleanGroupHtml = clean($group);
switch ($format) {
case 'rss':
header("Content-type: text/xml");
echo '' . "\n";?>
- :
+ :
/group.php?group=
- :
+ :
/group.php?group=
- Newsgroup at
+ Newsgroup at
en-US
';
echo ' PHP Mailing Lists';
echo ' ',
- htmlspecialchars($group, ENT_QUOTES, "UTF-8") . '';
+ $cleanGroupUrl . '">',
+ $cleanGroupHtml . '';
echo ' ';
echo '';
echo '';
- echo '' . htmlspecialchars($group, ENT_QUOTES, "UTF-8") . '
';
+ echo '' . $cleanGroupHtml . '
';
if ($i == 0) {
/* Special header of info for the main page for a group */
$groups = $nntpClient->listGroups($group);
@@ -92,7 +93,7 @@