Skip to content

Commit

Permalink
manager.c: Prevent path traversal with GetConfig.
Browse files Browse the repository at this point in the history
When using AMI GetConfig, it was possible to access files outside of the
Asterisk configuration directory by using filenames with ".." and "./"
even while live_dangerously was not enabled. This change resolves the
full path and ensures we are still in the configuration directory before
attempting to access the file.
  • Loading branch information
bkford authored and asterisk-org-access-app[bot] committed Dec 14, 2023
1 parent 183954b commit 424be34
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions main/manager.c
Expand Up @@ -3752,12 +3752,43 @@ void astman_live_dangerously(int new_live_dangerously)
live_dangerously = new_live_dangerously;
}

/**
* \brief Check if a file is restricted or not
*
* \return 0 on success
* \return 1 on restricted file
* \return -1 on failure
*/
static int restrictedFile(const char *filename)
{
if (!live_dangerously && !strncasecmp(filename, "/", 1) &&
strncasecmp(filename, ast_config_AST_CONFIG_DIR, strlen(ast_config_AST_CONFIG_DIR))) {
char *stripped_filename;
RAII_VAR(char *, path, NULL, ast_free);
RAII_VAR(char *, real_path, NULL, ast_free);

if (live_dangerously) {
return 0;
}

stripped_filename = ast_strip(ast_strdupa(filename));

/* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
if (stripped_filename[0] == '/') {
real_path = realpath(stripped_filename, NULL);
} else {
if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
return -1;
}
real_path = realpath(path, NULL);
}

if (!real_path) {
return -1;
}

if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
return 1;
}

return 0;
}

Expand All @@ -3770,6 +3801,7 @@ static int action_getconfig(struct mansession *s, const struct message *m)
const char *category_name;
int catcount = 0;
int lineno = 0;
int ret = 0;
struct ast_category *cur_category = NULL;
struct ast_variable *v;
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
Expand All @@ -3779,9 +3811,13 @@ static int action_getconfig(struct mansession *s, const struct message *m)
return 0;
}

if (restrictedFile(fn)) {
ret = restrictedFile(fn);
if (ret == 1) {
astman_send_error(s, m, "File requires escalated priveledges");
return 0;
} else if (ret == -1) {
astman_send_error(s, m, "Config file not found");
return 0;
}

cfg = ast_config_load2(fn, "manager", config_flags);
Expand Down

0 comments on commit 424be34

Please sign in to comment.