1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Patch inspired by one from Daniel Silverstone in Debian bug #229232:

We now have an option where a remote window title query returns a well-formed
response containing the empty string. This should keep stop any server-side
application that was expecting a response from hanging, while not permitting
the response to be influenced by an attacker.

We also retain the ability to stay schtum. The existing checkbox has thus
grown into a set of radio buttons.

I've changed the default to the "empty string" response, even in the backward-
compatibility mode of loading old settings, which is a change in behaviour;
any users who want the old behaviour back will have to explicitly select it. I
think this is probably the Right Thing. (The only drawback I can think of is
that an attacker could still potentially use the relevant fixed strings for
mischief, but we already have other, similar reports.)

[originally from svn r7043]
This commit is contained in:
Jacob Nevins 2006-12-31 15:33:33 +00:00
parent cd94e3bc3c
commit 4ae926fa8a
5 changed files with 60 additions and 13 deletions

View File

@ -1363,9 +1363,13 @@ void setup_config_box(struct controlbox *b, int midsession,
HELPCTX(features_retitle), HELPCTX(features_retitle),
dlg_stdcheckbox_handler, dlg_stdcheckbox_handler,
I(offsetof(Config,no_remote_wintitle))); I(offsetof(Config,no_remote_wintitle)));
ctrl_checkbox(s, "Disable remote window title querying (SECURITY)", ctrl_radiobuttons(s, "Response to remote title query (SECURITY):", 'q', 3,
'q', HELPCTX(features_qtitle), dlg_stdcheckbox_handler, HELPCTX(features_qtitle),
I(offsetof(Config,no_remote_qtitle))); dlg_stdradiobutton_handler,
I(offsetof(Config,remote_qtitle_action)),
"None", I(TITLE_NONE),
"Empty string", I(TITLE_EMPTY),
"Window title", I(TITLE_REAL), NULL);
ctrl_checkbox(s, "Disable destructive backspace on server sending ^?",'b', ctrl_checkbox(s, "Disable destructive backspace on server sending ^?",'b',
HELPCTX(features_dbackspace), HELPCTX(features_dbackspace),
dlg_stdcheckbox_handler, I(offsetof(Config,no_dbackspace))); dlg_stdcheckbox_handler, I(offsetof(Config,no_dbackspace)));

View File

@ -882,7 +882,7 @@ commands from the server. If you find PuTTY is doing this
unexpectedly or inconveniently, you can tell PuTTY not to respond to unexpectedly or inconveniently, you can tell PuTTY not to respond to
those server commands. those server commands.
\S{config-features-qtitle} Disabling remote \i{window title} querying \S{config-features-qtitle} Response to remote \i{window title} querying
\cfg{winhelp-topic}{features.qtitle} \cfg{winhelp-topic}{features.qtitle}
@ -899,8 +899,28 @@ service to have the new window title sent back to the server as if
typed at the keyboard. This allows an attacker to fake keypresses typed at the keyboard. This allows an attacker to fake keypresses
and potentially cause your server-side applications to do things you and potentially cause your server-side applications to do things you
didn't want. Therefore this feature is disabled by default, and we didn't want. Therefore this feature is disabled by default, and we
recommend you do not turn it on unless you \e{really} know what you recommend you do not set it to \q{Window title} unless you \e{really}
are doing. know what you are doing.
There are three settings for this option:
\dt \q{None}
\dd PuTTY makes no response whatsoever to the relevant escape
sequence. This may upset server-side software that is expecting some
sort of response.
\dt \q{Empty string}
\dd PuTTY makes a well-formed response, but leaves it blank. Thus,
server-side software that expects a response is kept happy, but an
attacker cannot influence the response string. This is probably the
setting you want if you have no better ideas.
\dt \q{Window title}
\dd PuTTY responds with the actual window title. This is dangerous for
the reasons described above.
\S{config-features-dbackspace} Disabling \i{destructive backspace} \S{config-features-dbackspace} Disabling \i{destructive backspace}

View File

@ -297,6 +297,11 @@ enum {
LD_ECHO /* local echo */ LD_ECHO /* local echo */
}; };
enum {
/* Actions on remote window title query */
TITLE_NONE, TITLE_EMPTY, TITLE_REAL
};
enum { enum {
/* Protocol back ends. (cfg.protocol) */ /* Protocol back ends. (cfg.protocol) */
PROT_RAW, PROT_TELNET, PROT_RLOGIN, PROT_SSH, PROT_RAW, PROT_TELNET, PROT_RLOGIN, PROT_SSH,
@ -486,7 +491,7 @@ struct config_tag {
int no_remote_wintitle; /* disable remote retitling */ int no_remote_wintitle; /* disable remote retitling */
int no_dbackspace; /* disable destructive backspace */ int no_dbackspace; /* disable destructive backspace */
int no_remote_charset; /* disable remote charset config */ int no_remote_charset; /* disable remote charset config */
int no_remote_qtitle; /* disable remote win title query */ int remote_qtitle_action; /* remote win title query action */
int app_cursor; int app_cursor;
int app_keypad; int app_keypad;
int nethack_keypad; int nethack_keypad;

View File

@ -324,7 +324,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "NoRemoteResize", cfg->no_remote_resize); write_setting_i(sesskey, "NoRemoteResize", cfg->no_remote_resize);
write_setting_i(sesskey, "NoAltScreen", cfg->no_alt_screen); write_setting_i(sesskey, "NoAltScreen", cfg->no_alt_screen);
write_setting_i(sesskey, "NoRemoteWinTitle", cfg->no_remote_wintitle); write_setting_i(sesskey, "NoRemoteWinTitle", cfg->no_remote_wintitle);
write_setting_i(sesskey, "NoRemoteQTitle", cfg->no_remote_qtitle); write_setting_i(sesskey, "RemoteQTitleAction", cfg->remote_qtitle_action);
write_setting_i(sesskey, "NoDBackspace", cfg->no_dbackspace); write_setting_i(sesskey, "NoDBackspace", cfg->no_dbackspace);
write_setting_i(sesskey, "NoRemoteCharset", cfg->no_remote_charset); write_setting_i(sesskey, "NoRemoteCharset", cfg->no_remote_charset);
write_setting_i(sesskey, "ApplicationCursorKeys", cfg->app_cursor); write_setting_i(sesskey, "ApplicationCursorKeys", cfg->app_cursor);
@ -606,7 +606,17 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppi(sesskey, "NoRemoteResize", 0, &cfg->no_remote_resize); gppi(sesskey, "NoRemoteResize", 0, &cfg->no_remote_resize);
gppi(sesskey, "NoAltScreen", 0, &cfg->no_alt_screen); gppi(sesskey, "NoAltScreen", 0, &cfg->no_alt_screen);
gppi(sesskey, "NoRemoteWinTitle", 0, &cfg->no_remote_wintitle); gppi(sesskey, "NoRemoteWinTitle", 0, &cfg->no_remote_wintitle);
gppi(sesskey, "NoRemoteQTitle", 1, &cfg->no_remote_qtitle); {
/* Backward compatibility */
int no_remote_qtitle;
gppi(sesskey, "NoRemoteQTitle", 1, &no_remote_qtitle);
/* We deliberately interpret the old setting of "no response" as
* "empty string". This changes the behaviour, but hopefully for
* the better; the user can always recover the old behaviour. */
gppi(sesskey, "RemoteQTitleAction",
no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
&cfg->remote_qtitle_action);
}
gppi(sesskey, "NoDBackspace", 0, &cfg->no_dbackspace); gppi(sesskey, "NoDBackspace", 0, &cfg->no_dbackspace);
gppi(sesskey, "NoRemoteCharset", 0, &cfg->no_remote_charset); gppi(sesskey, "NoRemoteCharset", 0, &cfg->no_remote_charset);
gppi(sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor); gppi(sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor);

View File

@ -65,6 +65,8 @@
#define has_compat(x) ( ((CL_##x)&term->compatibility_level) != 0 ) #define has_compat(x) ( ((CL_##x)&term->compatibility_level) != 0 )
char *EMPTY_WINDOW_TITLE = "";
const char sco2ansicolour[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; const char sco2ansicolour[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
#define sel_nl_sz (sizeof(sel_nl)/sizeof(wchar_t)) #define sel_nl_sz (sizeof(sel_nl)/sizeof(wchar_t))
@ -3791,8 +3793,11 @@ static void term_out(Terminal *term)
break; break;
case 20: case 20:
if (term->ldisc && if (term->ldisc &&
!term->cfg.no_remote_qtitle) { term->cfg.remote_qtitle_action != TITLE_NONE) {
p = get_window_title(term->frontend, TRUE); if(term->cfg.remote_qtitle_action == TITLE_REAL)
p = get_window_title(term->frontend, TRUE);
else
p = EMPTY_WINDOW_TITLE;
len = strlen(p); len = strlen(p);
ldisc_send(term->ldisc, "\033]L", 3, 0); ldisc_send(term->ldisc, "\033]L", 3, 0);
ldisc_send(term->ldisc, p, len, 0); ldisc_send(term->ldisc, p, len, 0);
@ -3801,8 +3806,11 @@ static void term_out(Terminal *term)
break; break;
case 21: case 21:
if (term->ldisc && if (term->ldisc &&
!term->cfg.no_remote_qtitle) { term->cfg.remote_qtitle_action != TITLE_NONE) {
p = get_window_title(term->frontend,FALSE); if(term->cfg.remote_qtitle_action == TITLE_REAL)
p = get_window_title(term->frontend, FALSE);
else
p = EMPTY_WINDOW_TITLE;
len = strlen(p); len = strlen(p);
ldisc_send(term->ldisc, "\033]l", 3, 0); ldisc_send(term->ldisc, "\033]l", 3, 0);
ldisc_send(term->ldisc, p, len, 0); ldisc_send(term->ldisc, p, len, 0);