Skip to content

Commit 5377c84

Browse files
author
Hai Zheng
committed
v7.9-a19: * **Misc** Disabled visits to static folder data files. (Alexander #335626)
1 parent 6585698 commit 5377c84

1 file changed

Lines changed: 66 additions & 4 deletions

File tree

src/file.cls.php

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,68 @@ class File {
1616

1717
const MARKER = 'LiteSpeed Operator';
1818

19+
/**
20+
* Whitelist .htaccess seeded into LITESPEED_STATIC_DIR. Anything not explicitly allowed returns 403.
21+
*
22+
* @since 7.9
23+
*/
24+
const STATIC_DIR_HTACCESS = <<<HTACCESS
25+
# BEGIN LSCACHE_STATIC_PROTECT
26+
# DO NOT EDIT — auto-generated by LiteSpeed Cache.
27+
# Whitelist: only listed root files and folders are publicly readable.
28+
29+
Options -Indexes
30+
31+
<IfModule mod_rewrite.c>
32+
RewriteEngine On
33+
34+
# Block dotfiles (.litespeed_conf.dat, .htaccess, etc.) anywhere in the tree
35+
RewriteRule (^|/)\.[^/]+$ - [F,L]
36+
37+
# Whitelisted root-level public files
38+
RewriteRule ^robots\.txt$ - [L]
39+
40+
# Whitelisted public asset folders
41+
RewriteRule ^(css|js|ucss|ccss|lqip|optimax|avatar|localres|crawler)(/|$) - [L]
42+
43+
# Default deny
44+
RewriteRule .* - [F,L]
45+
</IfModule>
46+
# END LSCACHE_STATIC_PROTECT
47+
HTACCESS;
48+
49+
/**
50+
* Seed .htaccess + robots.txt into LITESPEED_STATIC_DIR if missing
51+
*
52+
* @since 7.9
53+
*/
54+
public static function ensure_static_protection() {
55+
if (!is_dir(LITESPEED_STATIC_DIR)) {
56+
return;
57+
}
58+
$htaccess_path = LITESPEED_STATIC_DIR . '/.htaccess';
59+
if (is_file($htaccess_path)) {
60+
return;
61+
}
62+
$bytes = @file_put_contents($htaccess_path, self::STATIC_DIR_HTACCESS, LOCK_EX);
63+
64+
$robots_path = LITESPEED_STATIC_DIR . '/robots.txt';
65+
if (!is_file($robots_path)) {
66+
@file_put_contents($robots_path, "User-agent: *\nDisallow: /\n", LOCK_EX);
67+
}
68+
69+
$banner = sprintf(
70+
/* translators: %s: full path to the .htaccess file LiteSpeed Cache failed to create. */
71+
__('LiteSpeed Cache could not create %s. Sensitive files (configuration backups, debug logs) under this folder may be publicly accessible. Fix the directory permissions to restore protection.', 'litespeed-cache'),
72+
'<code>' . esc_html($htaccess_path) . '</code>'
73+
);
74+
if ($bytes === strlen(self::STATIC_DIR_HTACCESS)) {
75+
Admin_Display::dismiss_pin_by_content($banner, Admin_Display::NOTICE_RED, true);
76+
} else {
77+
Admin_Display::error($banner, false, true);
78+
}
79+
}
80+
1981
/**
2082
* Detect if an URL is 404
2183
*
@@ -146,17 +208,17 @@ public static function save( $filename, $data, $mkdir = false, $append = false,
146208

147209
try {
148210
mkdir($folder, 0755, true);
149-
// Create robots.txt file to forbid search engine indexes
150-
if (!file_exists(LITESPEED_STATIC_DIR . '/robots.txt')) {
151-
file_put_contents(LITESPEED_STATIC_DIR . '/robots.txt', "User-agent: *\nDisallow: /\n");
152-
}
153211
} catch (\ErrorException $ex) {
154212
return $silence ? false : sprintf(__('Can not create folder: %1$s. Error: %2$s', 'litespeed-cache'), $folder, $ex->getMessage());
155213
}
156214

157215
restore_error_handler();
158216
}
159217

218+
if (strpos($filename, LITESPEED_STATIC_DIR . '/') === 0) {
219+
self::ensure_static_protection();
220+
}
221+
160222
if (!file_exists($filename)) {
161223
if (!is_writable($folder)) {
162224
return $silence ? false : sprintf(__('Folder is not writable: %s.', 'litespeed-cache'), $folder);

0 commit comments

Comments
 (0)