ask-password: refuse agent requests with unsafe characters in prompt fields
The message, icon and id fields are written verbatim into single-line assignments of the [Ask] section of the agent request file, so a newline in them lets the caller append arbitrary further assignments. Agents let a later assignment override an earlier one, so an injected Socket= line redirects the password to a path of the injector's choosing. Validate the fields and refuse the request instead.
This commit is contained in:
committed by
Yu Watanabe
parent
a8e93919c3
commit
151dafcf16
@@ -828,6 +828,21 @@ static int create_socket(const char *askpwdir, char **ret) {
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
|
||||
bool ask_password_agent_prompt_fields_are_safe(const AskPasswordRequest *req) {
|
||||
/* These fields end up in single-line "Key=value" assignments in the agent request file, hence a
|
||||
* newline (or any other control character) in them would let the caller add further assignments to
|
||||
* the [Ask] section, which agents then happily honour. Only the characters string_is_safe() rejects
|
||||
* by default matter here, the rest is fine to appear in a prompt. */
|
||||
const StringSafeFlags flags = STRING_ALLOW_EMPTY | STRING_ALLOW_BACKSLASHES |
|
||||
STRING_ALLOW_QUOTES | STRING_ALLOW_GLOBS;
|
||||
|
||||
assert(req);
|
||||
|
||||
return (!req->message || string_is_safe(req->message, flags)) &&
|
||||
(!req->icon || string_is_safe(req->icon, flags)) &&
|
||||
(!req->id || string_is_safe(req->id, flags));
|
||||
}
|
||||
|
||||
int ask_password_agent(
|
||||
const AskPasswordRequest *req,
|
||||
AskPasswordFlags flags,
|
||||
@@ -850,6 +865,10 @@ int ask_password_agent(
|
||||
if (req->flag_file)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!ask_password_agent_prompt_fields_are_safe(req))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Password request contains unsafe characters, refusing.");
|
||||
|
||||
_cleanup_free_ char *askpwdir = NULL;
|
||||
r = get_ask_password_directory_for_flags(flags, &askpwdir);
|
||||
if (r < 0)
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct AskPasswordRequest {
|
||||
|
||||
int ask_password_tty(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret);
|
||||
int ask_password_plymouth(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret);
|
||||
bool ask_password_agent_prompt_fields_are_safe(const AskPasswordRequest *req) _pure_;
|
||||
int ask_password_agent(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret);
|
||||
int ask_password_auto(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user