Security Basics mailing list archives

Re: Looking for a "secure" alternative to MSN.


From: Oscar Calvo <ocalvo () s21sec com>
Date: Wed, 19 Jan 2011 18:18:10 +0100

I think the goal is not whether the IM client may be vulnerable to an attack or not, but whether it is possible to violate the communication between two clients. Thanks to the OTR plugin you can encrypt the two ends of the communication avoiding any succesful sniffing technique.


Oscar.


On 01/19/2011 09:38 AM, Jeffrey Walton wrote:
On Tue, Jan 4, 2011 at 3:43 AM, Oscar Calvo<ocalvo () s21sec com>  wrote:
Pidgin with OTR (Off The Record) Plugin

On 01/03/2011 07:43 PM, Todd Hughes wrote:
Client? Pidgin.

http://www.pidgin.im/
I don't believe Pidgin is secure. But I suppose its who you ask, and
what their definition of 'secure' is. I generally work against Howard
and LeBlanc's 'Writing Secure Code'; Apple's 'Secure Coding Guide';
and Wheeler's 'Secure Programming for Linux and Unix HOWTO'.

For example, the project chooses to ignore return values from
functions such as snprintf. So there's no way to tell if the function
succeeded, failed, or truncated a string. Worse, the project 'trucks
on' as if everything succeeded. It's hard to feel confident about
software which uses such insecure practices.

In all fairness to the project, return values from some functions,
such as memcpy, are useless.

Below is a quick audit of ...\pidgin and ...\libpurple. Files and line
numbers are listed. Notice that no return values are ever checked! And
functions such as sprintf and strcpy are still being used in 2010 and
beyond!

Jeff

Lukas wrote:
So, I'm looking for an IM client with strong encryption. Ideally with
audio/video support, and open source.
Like Msn sort of.. Preferably not some addon to msn though. I know there
is a lot of those.
It's incredible I can't find this. I'd be amazed if there's no IM client
that is capable of encryption.
jeffrey@studio:~/pidgin-2.7.9/pidgin$ ./audit-unsafe.sh
===== gtkaccount.c =====
856: g_snprintf(buf, sizeof(buf), "%d", int_value);
1143: g_snprintf(buf, sizeof(buf), "%d", int_val);
===== gtkblist.c =====
6504: g_snprintf(group_count, sizeof(group_count), "%d/%d",
===== gtkblist-theme.c =====
134: strncpy(copy->color, pair->color, sizeof(copy->color) - 1);
160: g_snprintf(font->color, sizeof(font->color),
===== gtkconv.c =====
6036: strcpy(with_font_tag, pre);
6038: strcpy(with_font_tag + pre_len + length, post);
5693: sprintf(pre_str, "%c%c%c",
5695: sprintf(post_str, "%c%c%c%c%c%c%c%c%c",
5702: sprintf(pre_str, "%c%c%c",
5704: sprintf(post_str, "%c%c%c%c%c%c%c%c%c",
5570: g_snprintf(colcode, sizeof(colcode), "#%02x%02x%02x",
5905: g_snprintf(buf2, sizeof(buf2),
5912: g_snprintf(buf2, sizeof(buf2),
5919: g_snprintf(buf2, BUF_LONG,
5946: g_snprintf(str, 1024, "***%s", alias_escaped);
5951: g_snprintf(str, 1024, "*%s*:", alias_escaped);
5959: g_snprintf(str, 1024, "%s ***%s", AUTO_RESPONSE, alias_escaped);
5962: g_snprintf(str, 1024, "***%s", alias_escaped);
5972: g_snprintf(str, 1024, "%s %s", alias_escaped, AUTO_RESPONSE);
5975: g_snprintf(str, 1024, "%s:", alias_escaped);
6010: g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>",
6018: g_snprintf(buf2, BUF_LONG, "<FONT %s>%s</FONT>  ", sml_attrib ?
sml_attrib : "", str);
6104: g_snprintf(tmp, sizeof(tmp),
6230: g_snprintf(tmp, sizeof(tmp),
===== gtkft.c =====
681: g_snprintf(buf, sizeof(buf), "<b>%s</b>",
===== gtkimhtml.c =====
5556: strcpy(color, "");
5570: strcpy(color, "");
852: strncpy(&tmp[1], color, 7);
4090: strncpy(&tmp[1], color, 7);
4114: strncpy(&tmp[1], color, 7);
3294: wpos = g_snprintf (ws, len, "%s", tag);
3298: wpos = g_snprintf (ws, len, "%s", tag);
3328: wpos = g_snprintf (ws, smilelen + 1, "%s", c);
4082: g_snprintf(str, sizeof(str), "FORECOLOR %s", color);
4106: g_snprintf(str, sizeof(str), "BACKCOLOR %s", color);
4130: g_snprintf(str, sizeof(str), "BACKGROUND %s", color);
4144: g_snprintf(str, sizeof(str), "FONT FACE %s", face);
4159: g_snprintf(str, sizeof(str), "FONT SIZE %d", size);
4814: g_snprintf(str, sizeof(str), "LINK %d", linkno++);
5090: g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
5097: g_snprintf(buf, sizeof(buf), "<font color=\"%s\">",&name[10]);
5100: g_snprintf(buf, sizeof(buf), "<font back=\"%s\">",&name[10]);
5103: g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">",&name[11]);
5106: g_snprintf(buf, sizeof(buf), "<font face=\"%s\">",&name[10]);
5109: g_snprintf(buf, sizeof(buf), "<font size=\"%s\">",&name[10]);
5119: str += g_snprintf(str, sizeof(buf) - (str - buf), "<span style='");
5134: str += g_snprintf(str, sizeof(buf) - (str - buf), "font-weight:
%s;", weight);
5141: str += g_snprintf(str, sizeof(buf) - (str - buf),
5151: str += g_snprintf(str, sizeof(buf) - (str - buf),
5166: str += g_snprintf(str, sizeof(buf) - (str - buf),
"text-decoration: underline;");
5171: g_snprintf(str, sizeof(buf) - (str - buf), "'>");
5551: g_snprintf(color, sizeof(color), "#%02x%02x%02x",
5565: g_snprintf(color, sizeof(color), "#%02x%02x%02x",
===== gtkimhtmltoolbar.c =====
237: g_snprintf(open_tag, 23, "#%02X%02X%02X",
314: g_snprintf(open_tag, 23, "#%02X%02X%02X",
672: g_snprintf(tip, sizeof(tip),
===== gtklog.c =====
513: strncpy(prev_top_month, month, sizeof(prev_top_month));
===== gtkmain.c =====
169: snprintf(errmsg, sizeof(errmsg), "Warning: waitpid() returned %d", pid);
663: snprintf(errmsg, sizeof(errmsg), "Warning: couldn't initialise
empty signal set");
668: snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d
for catching",
673: snprintf(errmsg, sizeof(errmsg), "Warning: couldn't include
signal %d for unblocking",
680: snprintf(errmsg, sizeof(errmsg), "Warning: couldn't set signal %d
to ignore",
687: snprintf(errmsg, sizeof(errmsg), "Warning: couldn't unblock signals");
===== gtknotify.c =====
549: g_snprintf(label_text, sizeof(label_text),
855: g_snprintf(label_text, sizeof(label_text),
1123: snprintf(key, sizeof(key), "%s - %s",
purple_account_get_username(account), purple_normalize(account, who));
===== gtkrequest.c =====
941: g_snprintf(buf, sizeof(buf), "%d", value);
===== gtkroomlist.c =====
648: g_snprintf(buf, sizeof(buf), "%d", myint);
===== gtksourceiter.c =====
490: strncpy (new_string, string, len);
===== gtkstatusbox.c =====
671: snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x",
2127: snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x",
===== gtkutils.c =====
2466: sprintf(tmp_buf, "%u", quality);
828: g_snprintf(buf, sizeof(buf), "%s (%s) (%s)",
833: g_snprintf(buf, sizeof(buf), "%s (%s)",
1671: g_snprintf(key, sizeof(key), "Name[%s]", langs[i]);
2893: snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x",
jeffrey@studio:~/pidgin-2.7.9/pidgin$

jeffrey@studio:~/pidgin-2.7.9/libpurple$ ./audit-unsafe.sh
===== account.c =====
113: g_snprintf(buf, sizeof(buf), "%d", setting->value.integer);
122: g_snprintf(buf, sizeof(buf), "%d", setting->value.boolean);
307: g_snprintf(buf, sizeof(buf), "%d", int_value);
345: g_snprintf(type_str, sizeof(type_str), "%u", err->type);
1549: g_snprintf(primary, sizeof(primary), _("Change password for %s"),
1587: g_snprintf(primary, sizeof(primary),
===== blist.c =====
151: g_snprintf(buf, sizeof(buf), "%d", purple_value_get_int(value));
160: g_snprintf(buf, sizeof(buf), "%d", purple_value_get_boolean(value));
316: g_snprintf(buf, sizeof(buf), "%d", account->perm_deny);
===== cipher.c =====
2911: sprintf(digest_s + (n * 2), "%02x", digest[n]);
===== conversation.c =====
1804: g_snprintf(tmp, sizeof(tmp),
1824: g_snprintf(tmp, sizeof(tmp),
===== desktopitem.c =====
507: strncpy (lang, locale, 2);
===== dnsquery.c =====
523: strncpy(dns_params.hostname, query_data->hostname,
sizeof(dns_params.hostname) - 1);
311: g_snprintf(servname, sizeof(servname), "%d", dns_params.port);
397: g_snprintf(s, sizeof(s), "/proc/%d/exe", ppid);
634: g_snprintf(message, sizeof(message), _("Error resolving %s:\n%s"),
637: g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
661: g_snprintf(message, sizeof(message), _("Error reading from
resolver process:\n%s"), g_strerror(errno));
665: g_snprintf(message, sizeof(message), _("Resolver process exited
without answering our request"));
790: g_snprintf(servname, sizeof(servname), "%d", query_data->port);
866: g_snprintf(message, sizeof(message), _("Thread creation failure: %s"),
939: g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
950: g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
===== dnssrv.c =====
383: strcpy(srvres->hostname, name);
621: strncpy(srvres->hostname, srv_data->pNameTarget, 255);
744: strncpy(internal_query.query, query, 255);
858: strncpy(internal_query.query, query, 255);
===== internal.h =====
156: * g_strlcpy/g_strlcpy directly. */
157:#define purple_strlcpy(dest, src) g_strlcpy(dest, src, sizeof(dest))
158:#define purple_strlcat(dest, src) g_strlcat(dest, src, sizeof(dest))
===== log.c =====
1704: strcpy(pathstr + strlen(pathstr) - 3, "idx");
1838: g_snprintf(convostart, length, "%s", temp);
===== network.c =====
193: g_snprintf(ip, 16, "%lu.%lu.%lu.%lu",
412: g_snprintf(serv, sizeof(serv), "%hu", port);
===== prefs.c =====
131: g_snprintf(buf, sizeof(buf), "%d", pref->value.integer);
164: g_snprintf(buf, sizeof(buf), "%d", pref->value.boolean);
===== proxy.c =====
982: strcpy(hostname, "localhost");
1116: strcpy(hostname, "localhost");
===== savedstatuses.c =====
1027: strcpy(tmp, "...");
1021: strncpy(buf, stripped, sizeof(buf));
288: g_snprintf(buf, sizeof(buf), "%lu", status->creation_time);
291: g_snprintf(buf, sizeof(buf), "%lu", status->lastused);
294: g_snprintf(buf, sizeof(buf), "%u", status->usage_count);
===== server.c =====
112: g_snprintf(lar->name, sizeof(lar->name), "%s", name);
812: g_snprintf(buf2, sizeof(buf2),
817: g_snprintf(buf2, sizeof(buf2),
===== stringref.c =====
73: strcpy(newref->value, value);
87: strcpy(newref->value, value);
107: vsprintf(newref->value, format, ap);
107: vsprintf(newref->value, format, ap);
===== stun.c =====
229: strcpy(nattype.publicip, ip);
===== upnp.c =====
395: strncpy(control_info.service_type, dd->service_type,
587: strncpy(dd->service_type, WAN_IP_CONN_SERVICE, sizeof(dd->service_type));
589: strncpy(dd->service_type, WAN_PPP_CONN_SERVICE, sizeof(dd->service_type));
775: strncpy(control_info.publicip, temp + 1,
810: strncpy(control_info.internalip,
891: strncpy(action_name, "AddPortMapping",
898: strncpy(action_name, "DeletePortMapping", sizeof(action_name));
965: strncpy(ar->protocol, protocol, sizeof(ar->protocol));
1012: strncpy(ar->protocol, protocol, sizeof(ar->protocol));
===== util.c =====
479: strcpy(buf, "Z");
3055: strcpy(&dest[j], "<BR>");
3961: strcpy(hostname, "localhost");
3192: strncpy(&ret[j], replacement, length_rep);
3358: strncpy(proto, uri, len);
3568: strncpy(new_url, s, len);
4206: strncpy(hex, str + ++i, 2);
4420: strncpy (retval, p, q - p + 1);
615: purple_strlcpy(buf, utf8);
4251: sprintf(buf + j, "%%%02X", utf_char[i]&  0xff);
4603: sprintf(msg, "unknown error (%d)", errnum);
4894: sprintf(buf + j, "%%%02x", utf_char[i]&  0xff);
135: g_snprintf(&ascii[i * 2], 3, "%02hhx", data[i]);
203: g_snprintf(&ascii[i * 3], 4, "%02hhx:", data[i]);
483: if(g_snprintf(buf, sizeof(buf), "%+03d:%02d", hrs, ABS(min))>  6)
487: if (g_snprintf(buf, sizeof(buf), "%+03d%02d", hrs, ABS(min))>  5)
1793: g_snprintf(buf, sizeof(buf), "%c", *c);
3001: g_snprintf(buf, sizeof(buf), "%s", tmp);
3025: g_snprintf(buf, sizeof(buf), "%s", tmp2 ? tmp2 : "");
3492: g_snprintf(port_str, sizeof(port_str), "443");
3494: g_snprintf(port_str, sizeof(port_str), "80");
===== xmlnode.c =====
642: vsnprintf(errmsg, sizeof(errmsg), msg, args);
jeffrey@studio:~/pidgin-2.7.9/libpurple$


--

*Oscar Calvo*
/Dept. Auditoria /

Tlf: +34 91 661 59 19
Móvil: + 34 628 476 785 // 436
www.s21sec.com <http://www.s21sec.com>, blog.s21sec.com <http://blog.s21sec.com>

logo S21sec

Salvo que se indique lo contrario, esta información es CONFIDENCIAL y contiene datos de carácter personal que han de ser tratados conforme a la legislación vigente en materia de protección de datos. Si usted no es destinatario original de este mensaje, le comunicamos que no está autorizado a revisar, reenviar, distribuir, copiar o imprimir la información en él contenida y le rogamos que proceda a borrarlo de sus sistemas.



Antes de imprimir este mensaje valora si verdaderamente es necesario. De esta forma contribuimos a la preservación del Medio Ambiente.


------------------------------------------------------------------------
Securing Apache Web Server with thawte Digital Certificate
In this guide we examine the importance of Apache-SSL and who needs an SSL certificate.  We look at how SSL works, how 
it benefits your company and how your customers can tell if a site is secure. You will find out how to test, purchase, 
install and use a thawte Digital Certificate on your Apache web server. Throughout, best practices for set-up are 
highlighted to help you ensure efficient ongoing management of your encryption keys and digital certificates.

http://www.dinclinx.com/Redirect.aspx?36;4175;25;1371;0;5;946;e13b6be442f727d1
------------------------------------------------------------------------


Current thread: