diff --git a/src/subscription.c b/src/subscription.c index af0012561..7789b0319 100644 --- a/src/subscription.c +++ b/src/subscription.c @@ -282,6 +282,7 @@ subscription_update (subscriptionPtr subscription, guint flags) subscription->updateState, subscription->updateOptions ); + update_request_allow_commands (request, TRUE); if (subscription_get_filter (subscription)) request->filtercmd = g_strdup (subscription_get_filter (subscription)); diff --git a/src/update.c b/src/update.c index b9ab8dd2e..369a2bf10 100644 --- a/src/update.c +++ b/src/update.c @@ -234,6 +234,13 @@ update_request_set_auth_value (UpdateRequest *request, const gchar* authValue) request->authValue = g_strdup (authValue); } +void +update_request_allow_commands (UpdateRequest *request, gboolean allowCommands) +{ + request->allowCommands = allowCommands; +} + + /* update result object */ updateResultPtr @@ -672,8 +679,14 @@ update_job_run (updateJobPtr job) /* everything starting with '|' is a local command */ if (*(job->request->source) == '|') { - debug1 (DEBUG_UPDATE, "Recognized local command: %s", job->request->source); - update_exec_cmd (job); + if (job->request->allowCommands) { + debug1 (DEBUG_UPDATE, "Recognized local command: %s", job->request->source); + update_exec_cmd (job); + } else { + debug1 (DEBUG_UPDATE, "Refusing to run local command from unexpected source: %s", job->request->source); + job->result->httpstatus = 403; /* Forbidden. */ + update_process_finished_job (job); + } return; } diff --git a/src/update.h b/src/update.h index d6244ad86..af29f8f97 100644 --- a/src/update.h +++ b/src/update.h @@ -103,6 +103,7 @@ struct _UpdateRequest { updateOptionsPtr options; /**< Update options for the request */ gchar *filtercmd; /**< Command will filter output of URL */ updateStatePtr updateState; /**< Update state of the requested object (etags, last modified...) */ + gboolean allowCommands; /**< Allow this requests to run commands */ }; /** structure to store results of the processing of an update request */ @@ -228,6 +229,21 @@ void update_request_set_source (UpdateRequest *request, const gchar* source); */ void update_request_set_auth_value (UpdateRequest *request, const gchar* authValue); +/** + * Allows *this* request to run local commands. + * + * At first it may look this flag should be in updateOptions, but we can + * take a safer path: feed commands are restricted to a few use cases while + * options are propagated to downstream requests (feed enrichment, comments, + * etc.), so it is a good idea to prevent these from running commands in the + * local system via tricky URLs without needing to validate these options + * everywhere (which is error-prone). + * + * @param request the update request + * @param can_run TRUE if the request can run commands, FALSE otherwise. + */ +void update_request_allow_commands (UpdateRequest *request, gboolean allowCommands); + /** * Creates a new update result for the given update request. *