-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathlock.php
More file actions
171 lines (146 loc) · 5.73 KB
/
lock.php
File metadata and controls
171 lines (146 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?php
/**
* File: lock.php
* Description: This file prevents access to static files & standalone php scripts if protected.
* For this file to function properly the .htaccess file must be altered.
* Author: Caseproof, LLC
* Copyright: 2004-2013, Caseproof, LLC
*/
/**
* Locks access to protected resources.
*/
function mepr_lock(): void
{
$root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root . '/wp-load.php')) {
require_once($root . '/wp-load.php');
} else {
require_once($root . '/wp-config.php');
}
defined('ABSPATH') || exit;
$mepr_uri = isset($_REQUEST['mepruri'])
? untrailingslashit(esc_url_raw(wp_unslash($_REQUEST['mepruri'])))
: esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));
$is_ssl = MeprUtils::is_ssl();
$server_port = intval($_SERVER['SERVER_PORT'] ?? 0);
if ($server_port <= 0 || $server_port > 65535) {
$server_port = $is_ssl ? 443 : 80;
}
$full_uri = 'http' . ($is_ssl ? 's' : '') . '://' .
sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'] ?? '')) .
(in_array($server_port, [80, 443], true) ? '' : ':' . $server_port) .
esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));
$mepr_full_uri = preg_replace('#^(https?://[^/]*).*$#', '$1', home_url()) . $mepr_uri;
$full_uri = preg_replace('#^(https?://[^/]*).*$#', '$1', $full_uri) . $mepr_uri;
$subdir = preg_replace('#^https?://[^/]+#', '', site_url());
$mepr_filename = basename($mepr_uri);
$from_abspath_uri = substr(str_replace($subdir, '', $mepr_uri), 1);
$mepr_full_filename = ABSPATH . $from_abspath_uri;
// Redirecting unless the correct home_url is used.
if ($mepr_full_uri !== $full_uri) {
wp_safe_redirect($mepr_full_uri);
exit;
}
// Figure out the rule hash for this uri.
$user = MeprUtils::get_currentuserinfo();
if ($user) {
$rule_hash = md5($mepr_uri . $user->ID . wp_salt());
} else {
$rule_hash = md5($mepr_uri . wp_salt());
}
// Make sure expired files are cleaned out.
mepr_clean_rule_files();
// Handle when a URI is locked.
if (MeprRule::is_uri_locked($mepr_uri)) {
$mepr_options = MeprOptions::fetch();
$delim = MeprAppCtrl::get_param_delimiter_char($mepr_options->unauthorized_redirect_url);
if ($mepr_options->redirect_on_unauthorized) { // Send to unauth page.
$redirect_url = $mepr_options->unauthorized_redirect_url . $delim . 'action=mepr_unauthorized&redirect_to=' . urlencode($mepr_full_uri);
} else { // Send to login page.
$redirect_url = $mepr_options->login_page_url('action=mepr_unauthorized&redirect_to=' . urlencode($mepr_full_uri));
}
// Handle SSL.
$redirect_url = ($is_ssl ? str_replace('http:', 'https:', $redirect_url) : $redirect_url);
MeprUtils::wp_redirect($redirect_url);
exit;
}
// Handle php files & directories
// At this point in the script the user has access
// so all we need to do is redirect them to the right place.
if (preg_match('/\.(php|phtml)/', $mepr_uri)) {
mepr_redirect_locked_uri($mepr_uri, $rule_hash);
} elseif (is_dir($mepr_full_filename)) {
if (file_exists($mepr_full_filename . '/index.php')) {
mepr_redirect_locked_uri($mepr_uri . '/index.php', $rule_hash);
} elseif (file_exists($mepr_full_filename . '/index.phtml')) {
mepr_redirect_locked_uri($mepr_uri . '/index.phtml', $rule_hash);
} elseif (file_exists($mepr_full_filename . '/index.htm')) {
mepr_render_locked_file($mepr_full_filename . '/index.htm');
} elseif (file_exists($mepr_full_filename . '/index.html')) {
mepr_render_locked_file($mepr_full_filename . '/index.html');
}
} else {
// Handle all other static file types.
mepr_redirect_locked_uri($mepr_uri, $rule_hash);
}
}
/**
* Redirects user to a locked URI after creating a temporary rule file.
*
* Creates a rule file to grant temporary access and redirects the user
* to the protected content.
*
* @since 1.0.0
*
* @throws Exception If the filesystem cannot be accessed.
*
* @param string $mepr_uri The URI being accessed.
* @param string $rule_hash The hash value used to create the rule file.
*/
function mepr_redirect_locked_uri($mepr_uri, $rule_hash)
{
$filesystem = MeprFilesystem::get();
$rule_dir = MeprRule::rewrite_rule_file_dir();
$filesystem->touch($rule_dir . '/' . $rule_hash);
setcookie('mplk', $rule_hash, (time() + 5));
MeprUtils::wp_redirect($mepr_uri);
exit;
}
/**
* Renders a protected file to the browser.
*
* Determines the file's mime type and outputs the file content with appropriate headers.
*
* @since 1.0.0
* @param string $filename Path to the file being rendered.
*/
function mepr_render_locked_file($filename)
{
// Trim any params from the filename.
$filename = preg_replace('#\?.*$#', '', $filename);
$info = wp_check_filetype($filename);
$file_contents = file_get_contents($filename);
header("Content-Type: {$info['type']}");
echo $file_contents; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
exit;
}
/**
* Removes expired rule files.
*
* Cleans up temporary rule files that are older than 60 seconds.
*
* @return void
*/
function mepr_clean_rule_files()
{
$filenames = glob(MeprRule::rewrite_rule_file_dir() . '/*', GLOB_NOSORT);
if (is_array($filenames) && !empty($filenames)) {
foreach ($filenames as $filename) {
if ((time() - filemtime($filename)) > 60) {
wp_delete_file($filename);
}
}
}
}
// Execute the lock function.
mepr_lock();