diff --git a/proxy/config.php b/proxy/config.php
index 1d90e38..73f081a 100644
--- a/proxy/config.php
+++ b/proxy/config.php
@@ -38,7 +38,7 @@ $mail_subscription_user_key = NULL;
// CAREFUL: only enable temporarily on debug systems. Will log all queries to given PUBLIC file
$debug = NULL; //'debug.log';
-// Local network interface or IP to be used for the relayed query
+// Local network interface or IP to be used for the relayed query
// This is usefull in some VPN configurations (see CURLOPT_INTERFACE)
$target_interface = NULL;
@@ -91,6 +91,10 @@ $rest_allowed_actions = array(
'getsingle' => array(
'first_name' => 'string',
'last_name' => 'string',
+ // the following means *all* remaining parameters will be
+ // added and sanitised as 'string'. Better leave it out
+ // if you know which parameters you expect
+ '*' => 'string',
),
),
),
diff --git a/proxy/proxy.php b/proxy/proxy.php
index e6bbee9..ba8a0f5 100644
--- a/proxy/proxy.php
+++ b/proxy/proxy.php
@@ -14,10 +14,10 @@ $civiproxy_logo = "
=> ''
* where type can be 'int', 'string' (unchecked),
*/
function civiproxy_get_parameters($valid_parameters) {
$result = array();
+ $default_sanitation = NULL;
foreach ($valid_parameters as $name => $type) {
+ if ($name == '*') {
+ // this sets default_sanitation
+ $default_sanitation = $type;
+ continue;
+ }
+
if (isset($_REQUEST[$name])) {
- $value = $_REQUEST[$name];
- if ($type=='int') {
- $value = (int) $value;
- } elseif ($type == 'string') {
- // TODO: sanitize? SQL?
- $value = $value;
- } elseif ($type == 'float2') {
- // TODO: check if safe wrt l10n. rather use sprintf
- $value = number_format($value, 2, '.', '');
- } elseif ($type == 'hex') {
- // hex code
- if (!preg_match("#^[0-9a-f]*$#i", $value)) {
- error_log("CiviProxy: removed invalid hex parameter: " . $value);
- $value = '';
- }
- } elseif ($type == 'email') {
- // valid email
- if (!preg_match("#^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$#i", $value)) {
- error_log("CiviProxy: removed invalid email parameter: " . $value);
- $value = '';
- }
- } elseif (is_array($type)) {
- // this is a list of valid options
- $requested_value = $value;
- $value = '';
- foreach ($type as $allowed_value) {
- if ($requested_value === $allowed_value) {
- $value = $requested_value;
- break;
- }
- }
- } else {
- error_log("CiviProxy: unknown type '$type'. Ignored.");
- $value = '';
+ $result[$name] = civiproxy_sanitise($_REQUEST[$name], $type);
+ }
+ }
+
+ // process wildcard elements
+ if ($default_sanitation !== NULL) {
+ // i.e. we want the others too
+ $remove_parameters = array('key', 'api_key', 'version', 'entity', 'action');
+ foreach ($_REQUEST as $name => $value) {
+ if (!in_array($name, $remove_parameters) && !isset($valid_parameters[$name])) {
+ $result[$name] = civiproxy_sanitise($value, $default_sanitation);
}
- $result[$name] = $value;
}
}
return $result;
}
+/**
+ * sanitise the given value with the given sanitiation type
+ */
+function civiproxy_sanitise($value, $type) {
+ if ($type=='int') {
+ $value = (int) $value;
+ } elseif ($type == 'string') {
+ // TODO: sanitize? SQL?
+ $value = $value;
+ } elseif ($type == 'float2') {
+ // TODO: check if safe wrt l10n. rather use sprintf
+ $value = number_format($value, 2, '.', '');
+ } elseif ($type == 'hex') {
+ // hex code
+ if (!preg_match("#^[0-9a-f]*$#i", $value)) {
+ error_log("CiviProxy: removed invalid hex parameter: " . $value);
+ $value = '';
+ }
+ } elseif ($type == 'email') {
+ // valid email
+ if (!preg_match("#^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$#i", $value)) {
+ error_log("CiviProxy: removed invalid email parameter: " . $value);
+ $value = '';
+ }
+ } elseif (is_array($type)) {
+ // this is a list of valid options
+ $requested_value = $value;
+ $value = '';
+ foreach ($type as $allowed_value) {
+ if ($requested_value === $allowed_value) {
+ $value = $requested_value;
+ break;
+ }
+ }
+ } else {
+ error_log("CiviProxy: unknown type '$type'. Ignored.");
+ $value = '';
+ }
+}
+
+
/**
* generates a CiviCRM REST API compliant error
* and ends processing
@@ -224,7 +248,7 @@ function civicrm_api3($entity, $action, $data) {
// extract site key
$site_keys = array_values($sys_key_map);
if (empty($site_keys)) civiproxy_http_error('No site key set.');
-
+
$query = $data; // array copy(!)
$query['key'] = $site_keys[0];
$query['json'] = 1;
@@ -247,7 +271,7 @@ function civicrm_api3($entity, $action, $data) {
}
$response = curl_exec($curlSession);
-
+
if (curl_error($curlSession)){
civiproxy_http_error(curl_error($curlSession));
} else {
diff --git a/proxy/rest.php b/proxy/rest.php
index e5b587b..d97efb7 100644
--- a/proxy/rest.php
+++ b/proxy/rest.php
@@ -44,7 +44,7 @@ if (empty($credentials['api_key'])) {
// check if the call itself is allowed
$action = civiproxy_get_parameters(array('entity' => 'string', 'action' => 'string', 'version' => 'int', 'json' => 'int', 'sequential' => 'int'));
if (!isset($action['version']) || $action['version'] != 3) {
- civiproxy_rest_error("Invalid entity/action.");
+ civiproxy_rest_error("API 'version' information missing.");
}
// in release 0.4, allowed entity/actions per IP were introduced. To introduce backward compatibility,