Skip to content

Commit 5a214be

Browse files
committed
1.13.2 security fix
1 parent 5005c09 commit 5a214be

File tree

3 files changed

+320
-1
lines changed

3 files changed

+320
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
$file_name = 'phpr_response.php';
3+
$current_file = PATH_APP.'/phproad/modules/phpr/classes/'.$file_name;
4+
$replacement_file = PATH_APP.'/modules/core/updates/framework/phproad/modules/phpr/classes/'.$file_name;
5+
if(!copy($replacement_file, $current_file)){
6+
throw new Phpr_ApplicationException('Could not copy '.$file_name.' to '.$current_file.' check write permissions for PHP');
7+
}
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
<?php
2+
3+
/**
4+
* Represents the application HTTP response.
5+
* An instance of this class is always available through the <em>$Phpr</em> class and you never need to create it manually:
6+
* <pre>Phpr::$response->redirect('http://google.com');</pre>
7+
* @documentable
8+
* @see Phpr_Request
9+
* @author LemonStand eCommerce Inc.
10+
* @package core.classes
11+
*/
12+
class Phpr_Response
13+
{
14+
const actionOn404Action = 'On404';
15+
const actionOnException = 'OnException';
16+
const controllerApplication = 'Application';
17+
18+
public static $defaultJsScripts = array( 'mootools.js', 'popups.js', 'phproad.js' );
19+
20+
/**
21+
* Opens a local URL (like "blog/edit/1")
22+
* @param string $URI Specifies the URI to open.
23+
*/
24+
public function open( $URI )
25+
{
26+
$Controller = null;
27+
$Action = null;
28+
$Parameters = null;
29+
$Folder = null;
30+
31+
Phpr::$router->route( $URI, $Controller, $Action, $Parameters, $Folder );
32+
33+
if ( $Action == self::actionOn404Action || $Action == self::actionOnException )
34+
$this->open404();
35+
36+
if ( !strlen($Controller) )
37+
$this->open404();
38+
39+
$Obj = Phpr::$classLoader->loadController($Controller, $Folder);
40+
if ( !$Obj )
41+
$this->open404();
42+
43+
if ( $Action == $Controller )
44+
$Action = 'Index';
45+
46+
if ( !$Obj->_actionExists($Action) )
47+
$this->open404();
48+
49+
$Obj->_run($Action, $Parameters);
50+
}
51+
52+
/**
53+
* Opens the "Page not found" page.
54+
* By default this method opens a page provided by the PHP Road.
55+
* You may supply the application 404 page by creating the On404() action in the Application Controller.
56+
*/
57+
public function open404()
58+
{
59+
// Try to execute the application controller On404 action.
60+
//
61+
$Controller = Phpr::$classLoader->loadController(self::controllerApplication);
62+
if ( $Controller != null && $Controller->_actionExists(self::actionOn404Action) )
63+
{
64+
$Controller->_run(self::actionOn404Action, array());
65+
exit;
66+
}
67+
68+
// Output the default 404 message.
69+
//
70+
include PATH_SYSTEM."/errorpages/404.htm";
71+
exit;
72+
}
73+
74+
/**
75+
* Opens the Error Page.
76+
* By default this method opens a page provided by the PHP Road.
77+
* You may supply the application error page by creating the OnException($Exception) action in the Application Controller.
78+
*/
79+
public function openErrorPage($exception)
80+
{
81+
if(ob_get_length())
82+
ob_clean();
83+
84+
// try to execute the application controller On404 action.
85+
$application = Phpr::$classLoader->loadController(self::controllerApplication);
86+
87+
if($application != null && $application->_actionExists(self::actionOnException)) {
88+
$application->_run(self::actionOnException, array($exception));
89+
90+
exit;
91+
}
92+
93+
$error = Phpr_ErrorLog::get_exception_details($exception);
94+
95+
// Output the default exception message.
96+
include PATH_SYSTEM . "/errorpages/exception.htm";
97+
exit;
98+
}
99+
100+
/**
101+
* Redirects the browser to a specific URL.
102+
* Note that this method terminates the script execution.
103+
* @documentable
104+
* @param string $url Specifies the target URL.
105+
* @param boolean $send_301_header Determines whether HTTP header <em>301 Moved Permanently</em> should be sent.
106+
*/
107+
public function redirect( $Uri, $Send301Header = false )
108+
{
109+
if ( !Phpr::$request->isRemoteEvent() )
110+
{
111+
if ($Send301Header)
112+
header ('HTTP/1.1 301 Moved Permanently');
113+
114+
switch (Phpr::$config->get( "REDIRECT", 'location' ))
115+
{
116+
case 'refresh' : header("Refresh:0;url=".$Uri); break;
117+
default : header("location:".$Uri); break;
118+
}
119+
}
120+
else
121+
{
122+
$output = "<script type='text/javascript'>";
123+
$output .= "(function(){window.location='".$Uri."';}).delay(100)";
124+
$output .= "</script>";
125+
echo $output;
126+
}
127+
128+
die;
129+
}
130+
131+
/**
132+
* Sends a cookie.
133+
* @documentable
134+
* @param string $name Specifies the name of the cookie.
135+
* @param string $value Specifies the cookie value.
136+
* @param string $expire Specifies a time the cookie expires, in days.
137+
* @param string $path Specifies the path on the server in which the cookie will be available on.
138+
* @param string $domain Specifies a domain that the cookie is available to.
139+
* @param string $secure Indicates that the cookie should only be transmitted over a secure HTTPS connection.
140+
*/
141+
public function setCookie( $Name, $Value, $Expire = 0, $Path = '/', $Domain = '', $Secure = null )
142+
{
143+
$_COOKIE[$Name] = $Value;
144+
145+
if ($Secure === null)
146+
{
147+
if (Phpr::$request->protocol() === 'https' && Phpr::$config->get('SECURE_COOKIES', true))
148+
$Secure = true;
149+
else
150+
$Secure = false;
151+
}
152+
153+
if ( Phpr::$request->isRemoteEvent() )
154+
{
155+
if (post('no_cookies'))
156+
return;
157+
158+
$output = "<script type='text/javascript'>";
159+
$duration = $Expire;
160+
$Secure = $Secure ? 'true' : 'false';
161+
162+
$output .= "Cookie.write('$Name', '$Value', {duration: $duration, path: '$Path', domain: '$Domain', secure: $Secure});";
163+
$output .= "</script>";
164+
echo $output;
165+
} else
166+
{
167+
if ($Expire > 0)
168+
$Expire = time() + $Expire*24*3600;
169+
170+
setcookie( $Name, $Value, $Expire, $Path, $Domain, $Secure );
171+
}
172+
}
173+
174+
/**
175+
* Adds <script> section to AJAX response containing a list of JavaScript and CSS
176+
* resources which should be loaded before the response text is rendered.
177+
*/
178+
public function addRemoteResources($css = array(), $javascript = array())
179+
{
180+
if (!$css && !$javascript)
181+
return;
182+
183+
$result = "<script type='text/javascript'>var phpr_resource_list_marker = 1;";
184+
if ($css)
185+
$result .= 'phpr_css_list = ["'.implode('","', $css).'"];';
186+
187+
if ($javascript)
188+
$result .= 'phrp_js_list = ["'.implode('","', $javascript).'"];';
189+
190+
$result .= '</script>';
191+
192+
echo $result;
193+
}
194+
195+
/**
196+
* Deletes a cookie.
197+
* @documentable
198+
* @see Phpr_Response::setCookie() setCookie()
199+
* @param string $name Specifies a name of the cookie.
200+
* @param string $path Specifies the path on the server
201+
* @param string $domain Specifies a domain that the cookie is available to.
202+
* @param string $Secure Indicates that the cookie should only be transmitted over a secure HTTPS connection.
203+
*/
204+
public function deleteCookie( $Name, $Path = '/', $Domain = '', $Secure = false )
205+
{
206+
if ( Phpr::$request->isRemoteEvent() )
207+
{
208+
if (post('no_cookies'))
209+
return;
210+
211+
$output = "<script type='text/javascript'>";
212+
$output .= "Cookie.dispose('$Name', {duration: 0, path: '$Path', domain: '$Domain'});";
213+
$output .= "</script>";
214+
echo $output;
215+
} else
216+
{
217+
setcookie( $Name, '', time()-360000, $Path, $Domain, $Secure );
218+
}
219+
}
220+
221+
/**
222+
* Sends AJAX response with information about exception.
223+
* Note that this method terminates the script execution.
224+
* @documentable
225+
* @param mixed $exception Specifies the exception object or message.
226+
* @param boolean $html Determines whether the response message should be in HTML format.
227+
* @param boolean $focus Determines whether the focusing Java Script code must be added to the response.
228+
* This parameter will work only if $exception is a Phpr_ValidationException object
229+
*/
230+
public function ajaxReportException( $Exception, $Html = false, $Focus = false )
231+
{
232+
/*
233+
* Prepare the message
234+
*/
235+
$Message = is_object($Exception) ? $Exception->getMessage() : $Exception;
236+
if ( $Html )
237+
$Message = nl2br($Message);
238+
239+
/*
240+
* Add focusing Java Script code
241+
*/
242+
if ( $Focus && $Exception instanceof Phpr_ValidationException )
243+
$Message .= $Exception->validation->getFocusErrorScript();
244+
245+
/*
246+
* Output headers and result
247+
*/
248+
echo "@AJAX-ERROR@";
249+
echo $Message;
250+
251+
/*
252+
* Stop the script execution
253+
*/
254+
die();
255+
}
256+
257+
/**
258+
* @ignore
259+
* This method is used by the PHP Road internally.
260+
* Outputs the requested Java Script resource.
261+
*/
262+
public static function processJavaScriptRequest()
263+
{
264+
if ( !isset($_GET['phpr_js']) )
265+
return;
266+
267+
// Sanitize the requested resource name
268+
//
269+
if ( !preg_match("/^([a-zA-Z0-9_\.]*\.js|defaults|\|)*/", $_GET['phpr_js']) )
270+
die;
271+
272+
// Prepare the result string
273+
//
274+
$result = null;
275+
276+
foreach ( explode( "|", $_GET['phpr_js'] ) as $file )
277+
{
278+
279+
$files = ($file == "defaults") ? self::$defaultJsScripts : array($file);
280+
281+
foreach ( $files as $file )
282+
{
283+
$file_parts = pathinfo($file);
284+
if($file_parts['extension'] == 'js') {
285+
$filePath = PATH_SYSTEM . "/javascript/" . $file_parts['basename'];
286+
if ( file_exists( $filePath ) ) {
287+
$result .= file_get_contents( $filePath );
288+
}
289+
}
290+
}
291+
}
292+
293+
// Prepare the output buffering with compressing
294+
//
295+
if ( function_exists('ob_gzhandler') && !!ini_get('zlib.output_compression') )
296+
ob_start("ob_gzhandler");
297+
298+
// Output the headers
299+
//
300+
header("Content-type: text/javascript; charset: UTF-8");
301+
header("Vary: Accept-Encoding");
302+
303+
// Output the result string
304+
//
305+
echo $result;
306+
307+
die;
308+
}
309+
}
310+
311+
?>

updates/version.dat

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,5 @@
462462
#1.12.2 Added the force parameter to update request events.
463463
#1.12.3 Minor fix in core_modulemanager. This resolves damanic/ls1-module-updatecenter#1
464464
#1.13.0|@1.13.0 Added subscribe to crontab and add to cronjob support
465-
#1.13.1 Bug Fix: sql now() being compared to localised PHP datetime causing cron timing issues.
465+
#1.13.1 Bug Fix: sql now() being compared to localised PHP datetime causing cron timing issues.
466+
#1.13.2|@1_13_2_framework_update Security fix

0 commit comments

Comments
 (0)