Skip to content

Commit af97a93

Browse files
committed
✨ Enhance security and validation in CSS proxy handling 🛡️🔒
- Added access check for chat session to ensure only authorized users can proceed. - Implemented validation for co-browse session URL to prevent unauthorized access. - Added checks to ensure CSS URL belongs to the co-browse session origin. - Introduced validation to reject private or loopback IP addresses for CSS downloads.
1 parent b1e6b90 commit af97a93

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

lhc_web/modules/lhcobrowse/proxycss.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@
1212
$browse = erLhcoreClassCoBrowse::getBrowseInstanceByOnlineUser($ouser);
1313
} else {
1414
$chat = erLhcoreClassChat::getSession()->load('erLhcoreClassModelChat', $Params['user_parameters']['chat_id']);
15+
if (!erLhcoreClassChat::hasAccessToRead($chat)) {
16+
exit;
17+
}
1518
$browse = erLhcoreClassCoBrowse::getBrowseInstance($chat);
1619
}
1720

21+
// Require a co-browse session URL to bind the fetch origin
22+
if (empty($browse->url)) {
23+
exit;
24+
}
25+
1826
$base = trim($_GET['base']);
1927

2028
if (!filter_var($base, FILTER_VALIDATE_URL)) {
@@ -28,6 +36,14 @@
2836
exit;
2937
}
3038

39+
// Bind to the co-browse session origin
40+
$browseUrl = parse_url($browse->url);
41+
$browseOrigin = ($browseUrl['scheme'] ?? '') . '://' . ($browseUrl['host'] ?? '') . (isset($browseUrl['port']) ? ':' . $browseUrl['port'] : '');
42+
$requestOrigin = $url['scheme'] . '://' . $url['host'] . (isset($url['port']) ? ':' . $url['port'] : '');
43+
if ($browseOrigin !== $requestOrigin) {
44+
exit;
45+
}
46+
3147
// Some basic validation
3248
if (isset($url['host']) && $url['host'] != '' && strpos($_GET['css'], erLhcoreClassSystem::getHost()) === false) {
3349

@@ -52,9 +68,28 @@
5268
exit;
5369
}
5470

71+
// CSS URL must belong to the co-browse session origin
72+
$cssOrigin = $urlCSS['scheme'] . '://' . $urlCSS['host'] . (isset($urlCSS['port']) ? ':' . $urlCSS['port'] : '');
73+
if ($cssOrigin !== $browseOrigin) {
74+
exit;
75+
}
76+
5577
$urlCSSDownload = $_GET['css'];
5678
}
5779

80+
// Resolve host and reject private/loopback destinations
81+
$downloadHost = parse_url($urlCSSDownload, PHP_URL_HOST);
82+
if ($downloadHost === null || $downloadHost === '') {
83+
exit;
84+
}
85+
$resolvedIp = gethostbyname($downloadHost);
86+
if ($resolvedIp === $downloadHost || !filter_var($resolvedIp, FILTER_VALIDATE_IP)) {
87+
exit;
88+
}
89+
if (!filter_var($resolvedIp, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
90+
exit;
91+
}
92+
5893
$ch = curl_init();
5994
curl_setopt($ch, CURLOPT_URL, $urlCSSDownload);
6095
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

0 commit comments

Comments
 (0)