[tin-bugs] Possible shell injection via group name

Urs Janßen urs at tin.org
Tue Apr 14 17:02:24 CEST 2026


On Tue, Apr 14, 2026 at 03:18:40PM +0200, Adam W. wrote:
> 1. User configures a signature command containing %G
> 2. Group name is substitued to the shell command
> 3. Group name is wrapped in double quotes (sigfile.c, 
>    msg_write_signature()), but it assumes that the group name is sane. 
>    Double quotes or other shell characters, like `, $ or \, are not 
>    escaped
> 4. Malicious server sends a group called: group"; rm -rf ~;"

that's not a valid group name. group names must not contain
space (0x20), but I didn't check tins code if it validates it
(everywhere), but if e.g. LIST ACTIVE/LIST COUNTS is used
(default), the response is splitted at whitespaces, so such a
group will never make it into the list of know groups to tin
(cut at first space);

you could some junk in your newsrc, group name are not splitted
at WS when parsing it but at : or ! but then it would need a server
to also hold some matching junk so you could try to post something
and thus invoke signature generattion expanding %G - very very
hypothetic. anyway, rejecting groups with WS in the from newsrc
is easy:

=== modified file 'src/newsrc.c'
--- old/src/newsrc.c	2026-04-12 08:34:09 +0000
+++ new/src/newsrc.c	2026-04-14 14:30:27 +0000
@@ -1754,6 +1754,9 @@
 	tmp = ptr;							/* Keep this blank for later */
 	*(ptr++) = '\0';					/* Terminate the group name */
 
+	if (strpbrk(ptr, " \t")) != NULL)	/* minimalistic name validation */
+		return NULL;
+
 #if 0
 	if (ptr == NULL)					/* No seq info, so return a blank */
 		return tmp;



leaving the -L cmd.-line or 'L' cmd. case where the server may 
return an (not yet validated group name). something like the above
in select.c:lookup_msgid() ~2025 should do, e.g.

=== modified file 'src/select.c'
--- old/src/select.c	2026-04-07 20:02:10 +0000
+++ new/src/select.c	2026-04-14 14:59:03 +0000
@@ -2022,8 +2022,13 @@
 								}
 							}
 						}
-						if (x)
+						if (x) {
+							if ((e = strpbrk(x, " \t"))) {
+								if (e < strchr(x, ':'))
+									return NULL;
+							}
 							return x;
+						}
 
 						if (!r) {
 #		ifdef DEBUG



I may have "overlooked" a way where tin uses a server replied
groupname which isn't rejected beforehand (and just rejecting
the ones with WS may not be enough), but as the scenario is very
hypothetic ...

> 5. A malicious command gets injected into popen()
> 
> Do you think it's a real vulnerability?

no really, I bet there are much more likely code injection
possibillities in the code :-P

> string.c contains sh_format(), maybe it would be a good idea to use it?

as long as you don't break the functionallity of e.g.

sigfile=!echo %G|tr '[A-M][a-m][N-Z][n-z]' '[N-Z][n-z][A-M][a-m]'

feel free to send a patch.



More information about the tin-bugs mailing list