Extras Security Policy
The MODX Security Team is not responsible for Extras for MODX, nor any security issues found within them. When a vulnerability is found in a MODX Extra, the Security Team will be notified and the author will be contacted regarding the issue. The author will be given a reasonable deadline by which to fix the issue. If the deadline is not met, the Extra will be removed from the official MODX Extras repository and a public advisory against the Extra will be released. Deadlines will be set by the Security Team in accordance with the severity of the issue. MODX or the Security Team will not audit or review Extras hosted on any non-official Provider.

<?php // highlight $modx->sanitize($mixed); // array $modx->sanitizeString($string); // only string
BUT, if you dig the code, it sanitize ASCII regex only.
You should create your own method to fit your characters if they are not ASCII texts.
Revo still misses the even trigger for TransAlias plugin like Evo has.
<?php //highlight $object = new MyClass($modx, $scriptProperties); // still having the raw values, absolutely dangerous! $object->submitMyForm($_POST); // absolutely dangerous! $object->property = $_POST['property']; // absolutely dangerous!
<?php //highlight $sanitizedPosts = $modx->sanitize($_POST); $_POST = array(); $object->submitMyForm($sanitizedPosts); // recommended!
<?php //highlight $sanitizedGets = $modx->sanitize($_GET); $_GET= array(); $object->submitMyForm($sanitizedGets); // recommended!
<?php //highlight
$scriptProperties['param'] = !empty($_GET['param']) ? $modx->sanitizeString($_GET['param']) : ''; // recommended!
$config['param'] = $modx->getOption('param', $scriptProperties, 'defaultValue');
<?php //highlight
class MyClass {
// dangerous
public function myFunction () {
$title = $_POST['title'];
echo $title;
}
// recommended
public function myFunction2 ($sanitizedPost) {
$title = $sanitizedPost['title'];
echo $title;
}
}
<?php
if (!defined('IN_MANAGER_MODE')) {
return;
// or
// die();
}
<?php // ... include the class file here ... $modx = new modX(); $sanitizedRequests = $modx->sanitize($_REQUEST); // recommended, will be applied to all $_GET, $_POST, $_COOKIE $_REQUEST = array(); $_REQUEST = sanitizedRequests; ... proceed ...
About the file inclusion and if this is about the front-end AJAX, you can set the ajax processor using the MODX’s resource.
Use a blank template to that resource, and make a snippet that calls the real AJAX processor file.
That will make the $modx object available to that processor.
You do not need to include the MODX’s core file again => that will make the direct access to the file become PHP Fatal Error!
<?php
/**
* for FormIt's hook
* http://modxcms.com/forums/index.php/topic,60716.msg345837.html#msg345837
*/
if (get_magic_quotes_gpc ()) {
if (!function_exists('stripslashes_gpc')) {
function stripslashes_gpc(&$value) {
$value = stripslashes($value);
}
}
array_walk_recursive($_GET, 'stripslashes_gpc');
array_walk_recursive($_POST, 'stripslashes_gpc');
array_walk_recursive($_COOKIE, 'stripslashes_gpc');
array_walk_recursive($_REQUEST, 'stripslashes_gpc');
}
$defaultCorePath = $modx->getOption('core_path') . 'components/mySnippet/';
$snippetCorePath = $modx->getOption('mySnippet.core_path', null, $defaultCorePath);
$obj = $modx->getService('mySnippetClassMap', 'MyClass', $snippetCorePath . 'model/mySnippet/');
if (!($obj instanceof MyClass))
return '';
$obj->initialize($modx->context->get('key'));
/**
* Submission posting into the database
*/
if (!empty($hook) && !empty($_POST)) {
$allFormFields = $hook->getValues();
$report = $obj->submitForm($allFormFields); // XXX This is the submission! XXX
if ($report !== true) {
$hook->addError('error_message', $report);
return FALSE;
} else {
$modx->setPlaceholder('mySnippet.error.error_message', '');
return TRUE;
}
}
return '';
<?php
class MyClass {
// ...
<?php
/**
* Sanitize then submit
* @param array $entries POST array
* @return bool all valid and saved, or return FALSE
*/
public function submitForm($entries) {
$sanitizedEntries = $this->cleanInput($entries); // Sanitize here
$saveNewSubmit = $this->_saveNewSubmit ($sanitizedEntries); // This is the submission each by each.
if ($saveNewSubmit !== TRUE) {
return $saveNewSubmit;
}
return TRUE;
}
<?php
/**
* 1. Filter MODX's tag
* 2. Internationalization
* 3. Sanitizing user input from hacking
* @param array $entries raw input strings
* @return array sanitized strings in an array
*/
public function cleanInput($entries) {
$entries = $this->_trimWhiteSpaces($entries);
$entries = $this->utf8Rin($entries);
$entries = $this->htmLawed($entries, null, array(
'safe' => 1,
'deny_attribute' => 'style',
'clean_ms_char' => 1,
));
return $entries;
}
<?php
/**
* Trimming white spaces
* @param string $source text to be trimmed
* @return string trimmed text
*/
private function _trimWhiteSpaces($source) {
if (is_array($source)) {
foreach ($source as $k => $v) {
$source[$k] = $this->_trimWhiteSpaces($v);
}
} else {
$source = trim($source);
$source = preg_replace("/\s\s+/", " ", $source);
}
return $source;
}
<?php
/**
*
* Encoding using the class from
* @author Rin <http://forum.dklab.ru/profile.php?mode=viewprofile&u=3940>
* @link http://forum.dklab.ru/viewtopic.php?p=91015#91015
* @param mixed $source text to be converted
* @param string $callback call back function's name
* @param array $callbackParams call back parameters (in an array)
* @return mixed converted text
*/
public function utf8Rin($source, $callback = null, $callbackParams = array()) {
$path = $this->config['corePath'] . 'includes/utf8-rin/';
include_once $path . 'ReflectionTypehint.php';
include_once $path . 'UTF8.php';
if ($callback === null) {
$callback = 'convert_to';
}
if (is_array($source)) {
foreach ($source as $k => $v) {
$source[$k] = $this->utf8Rin($source[$k], $callback, $callbackParams);
}
} else {
if (empty($callbackParams)) {
$callbackParams = array(mb_detect_encoding($source));
}
$callbackParams = array_merge(array($source), $callbackParams);
$source = call_user_func_array(array('UTF8', $callback), $callbackParams);
}
return $source;
}
<?php
/**
* Sanitizing string from 3rd party
* @link http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/
* @param mixed $source text to be converted
* @param string $callback call back function's name
* @param array $callbackParams call back parameters (in an array)
* @return mixed converted text
*/
public function htmLawed($source, $callback=null, array $callbackParams = array()) {
$path = $this->config['corePath'] . 'includes/htmLawed/';
include_once $path . 'htmLawed.php';
if ($callback === null) {
$callback = 'htmLawed';
}
if (is_array($source)) {
foreach ($source as $k => $v) {
$source[$k] = $this->htmLawed($source[$k], $callback, $callbackParams);
}
} else {
$callbackParams = array_merge(array($source), $callbackParams);
$source = call_user_func_array($callback, $callbackParams);
}
return $source;
}
<?php
// until end class
}
<?php //highlight $sanitizedPosts = $modx->sanitize($_POST); $_POST = array(); $_POST = sanitizedPosts; // also can be done
<?php
$myObject = $modx->getObject('myClass', $myPK);
if ($myObject) {
/* fromArray() calls set() for each $_POST var that matches a field in your object */
$myObject->fromArray($_POST);
/* save() uses prepared statement bindings to automatically quote the values being sent to the db */
$myObject->save();
}
<?php //highlight $sanitizedPosts = $modx->sanitize($_POST); $_POST = array(); $_POST = sanitizedPosts; // also can be done