View Issue Details

IDProjectCategoryView StatusLast Update
0008882mantisbtotherpublic2008-10-18 18:32
Reporterpardini Assigned Tojreese  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.1.1 
Target Version1.1.3Fixed in Version1.1.3 
Summary0008882: Gravatar causes annoying security popups on IE when using Mantis over HTTPS/SSL
Description

When using Mantis over HTTPS/SSL, the Gravatar image URL is a common HTTP URL which causes boring Internet Explorer popups on almost every page.

This is a very common problem when using HTTPS, unfortunately Gravatar does not offer an HTTPS endpoint (that I know of).

One solution would be to 'proxy' all gravatar requests through a Mantis PHP file, like 'user_show_avatar.php'. This PHP file would be called just like every other Mantis page, over HTTPS, and would then proxy the request to gravatar, handling HTTP caching headers correctly to reduce the load.

This maybe could be also interesting for abstracting the avatar storage method (like the local avatars in 0008257).

Steps To Reproduce

1) Use a Mantis install over HTTPS
2) Use Internet Explorer, any version
3) Hit a page where an avatar would normally be shown
4) Security popup comes and annoys you
5) Your users get mad

Tagsavatar, https
Attached Files
user_api_gravatar_proxy.patch (1,632 bytes)   
Index: user_api.php
===================================================================
RCS file: /var/lib/cvs/mantis/core/user_api.php,v
retrieving revision 1.5
diff -u -r1.5 user_api.php
--- user_api.php	10 Feb 2008 00:49:03 -0000	1.5
+++ user_api.php	12 Feb 2008 17:22:48 -0000
@@ -649,18 +649,22 @@
 	* in this first implementation, only gravatar.com avatars are supported
 	* @return array|bool an array( URL, width, height ) or false when the given user has no avatar
 	*/
-	function user_get_avatar( $p_user_id ) {
+	function user_get_avatar( $p_user_id, $p_use_proxy_page = true) {
 		$t_email = strtolower( user_get_email( $p_user_id ) );
 		if ( is_blank( $t_email ) ) {
 			$t_result = false;
 		} else {
-			$t_default_image = config_get( 'default_avatar' );
 			$t_size = 80;
-			$t_avatar_url = "http://www.gravatar.com/avatar.php?gravatar_id=" . md5( $t_email ) .
-				"&default=" . urlencode( $t_default_image ) .
-				"&size=" . $t_size .
-				"&rating=G";
-			$t_result = array( $t_avatar_url, $t_size, $t_size );
+			if ($p_use_proxy_page) {
+				$t_result = array( 'user_avatar_image.php?id='.$p_user_id, $t_size, $t_size );
+			} else {
+				$t_default_image = config_get( 'default_avatar' );
+				$t_avatar_url = "http://www.gravatar.com/avatar.php?gravatar_id=" . md5( $t_email ) .
+					"&default=" . urlencode( $t_default_image ) .
+					"&size=" . $t_size .
+					"&rating=G";
+				$t_result = array( $t_avatar_url, $t_size, $t_size );
+			}
 		}
 
 		return $t_result;
--- user_avatar_image.php
+++ user_avatar_image.php
@@ -0,0 +1,0 @@


user_api_gravatar_proxy.patch (1,632 bytes)   
user_avatar_image.php (3,481 bytes)   
<?php
# Mantis - a php based bugtracking system

# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
# Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net

# Mantis is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Mantis is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.

	# --------------------------------------------------------
	# $Id: user_avatar_image.php,v 1.1 2008-02-12 22:06:45 ricardop Exp $
	# --------------------------------------------------------

	require_once( 'core.php' );

	$t_core_path = config_get( 'core_path' );

	require_once( $t_core_path . 'user_api.php' );
	
	$user_id = gpc_get_int( 'id' );
	
	$avatarDef = user_get_avatar( $user_id, false);
	$avatarURL = $avatarDef[0];
	
	if ($avatarURL) {
		ob_end_clean();
		ob_start();
		
		// Request headers. We take these from the request we received, and relay it back to gravatar.com
		$header = array();
		if ($_SERVER['HTTP_PRAGMA']) $header[] = 'Pragma: no-cache';
		if ($_SERVER['HTTP_CACHE_CONTROL']) $header[] = 'Cache-Control: no-cache';
		if ($_SERVER['HTTP_IF_MODIFIED_SINCE']) $header[] = 'If-Modified-Since: '.$_SERVER['HTTP_IF_MODIFIED_SINCE'].'';
		if ($_SERVER['HTTP_IF_NONE_MATCH']) $header[] = 'If-None-Match: '.$_SERVER['HTTP_IF_NONE_MATCH'].'';
		if ($_SERVER['HTTP_USER_AGENT']) $header[] = 'User-Agent: '.$_SERVER['HTTP_USER_AGENT'].'';
		
		if ($_SERVER['HTTP_ACCEPT']) $header[] = 'Accept: '.$_SERVER['HTTP_ACCEPT'].'';
		if ($_SERVER['HTTP_ACCEPT_LANGUAGE']) $header[] = 'Accept-Language: '.$_SERVER['HTTP_ACCEPT_LANGUAGE'].'';
		if ($_SERVER['HTTP_ACCEPT_ENCODING']) $header[] = 'Accept-Encoding: '.$_SERVER['HTTP_ACCEPT_ENCODING'].'';
		if ($_SERVER['HTTP_ACCEPT_CHARSET']) $header[] = 'Accept-Charset: '.$_SERVER['HTTP_ACCEPT_CHARSET'].'';
		
		$ch = curl_init();

		// set URL and other appropriate options
		curl_setopt($ch, CURLOPT_URL, $avatarURL);
		curl_setopt($ch, CURLOPT_HEADER, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 );
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

		// grab URL and pass it to the browser
		$response = curl_exec($ch);
		$info = curl_getinfo($ch);

		$code = $info['http_code'];
		$type = $info['content_type'];
		$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
		curl_close($ch);
		$headers = substr($response, 0, $header_size);
		$body = substr($response, $header_size);
				
		// PHP insists in sending some unwanted headers, clean those
		ob_end_clean();
		header("Cache-Control: ");
		header("Pragma: ");
		header("Expires: ");
		header("Date: ");
		header("ETag: ");
		header("Last-Modified: ");
		header("Age: ");
		header("Via: ");
				
		// Proxy the headers, directly to the client. This includes the status code. Clean the response first.
		$headers_array = explode("\n", $headers);
		foreach ($headers_array as $oneHeader) {
			header(trim($oneHeader));
		}
		echo $body;
		die(0);
	}
	
	
user_avatar_image.php (3,481 bytes)   
user_api-tuxsoul.diff (844 bytes)   
--- ../temp/mantis-1.1.2/core/user_api.php	2007-10-14 17:35:35.000000000 -0500
+++ /var/www/bts-update/core/user_api.php	2008-08-04 13:15:41.000000000 -0500
@@ -655,7 +655,18 @@
 		} else {
 			$t_default_image = config_get( 'default_avatar' );
 			$t_size = 80;
-			$t_avatar_url = "http://www.gravatar.com/avatar.php?gravatar_id=" . md5( $t_email ) .
+
+	 		$t_use_ssl = false;
+			if ( isset( $_SERVER['HTTPS'] ) && ( strtolower( $_SERVER['HTTPS'] ) != 'off' ) ) {
+				$t_use_ssl = true;
+			}
+
+			if ( !$t_use_ssl )
+				$t_gravatar_domain = "http://www.gravatar.com/";
+			else
+				$t_gravatar_domain = "https://secure.gravatar.com/";
+				
+			$t_avatar_url = $t_gravatar_domain . "avatar.php?gravatar_id=" . md5( $t_email ) .
 				"&amp;default=" . urlencode( $t_default_image ) .
 				"&amp;size=" . $t_size .
 				"&amp;rating=G";
user_api-tuxsoul.diff (844 bytes)   

Activities

jreese

jreese

2008-02-12 10:59

reporter   ~0017027

<rant> This is one of the dumbest IE-isms around. The use of normal HTTP content in HTTPS pages is a Good Thing for images and such, because it's faster and reduces the load on the server for things that don't need to be sent securely. And giving a user a popup in this case does nothing for security, because it doesn't tell you what is insecure, and so people just learn to ignore it anyways. </rant>

Anyways, I agree that we shouldn't be annoying the users, and I do think it might be a good solution to use a proxy page, but I will leave this for Giallu, as he implemented the avatar system.

pardini

pardini

2008-02-12 17:14

reporter   ~0017032

Attached is the proposed proxy page.
The page is insecure and has all kinds of coding standards problems, but it does work -- I dunno about the caching but I think it does work.
The patch to user_api.php introduces a new parameter to user_get_avatar for it to use the proxy page. I hope it helps, or at least serves as a starting point.

tuxsoul

tuxsoul

2008-08-04 14:44

reporter   ~0019029

Gravatar also support ssl protocol, maybe can check:
http://blog.gravatar.com/2008/03/14/big-changes-afoot/

I'm a newbie, but append a small patch, if possible have this in stable version ? :-D, sorry my english is bad, greeting's ;-).

dominik

dominik

2008-08-27 14:01

reporter   ~0019255

Nice and easy solution. I would appreciate it, if it becomes part of the official mantis too ;-)

pardini

pardini

2008-08-27 15:31

reporter   ~0019257

Agreed. tuxsoul's solution is much better since Gravatar has an SSL site.

jreese

jreese

2008-08-28 09:50

reporter   ~0019265

Fix to use Gravatar over SSL has been committed to SVN 1.1.x branch, r5529, and trunk, r5530.

Related Changesets

MantisBT: master-1.1.x cd3f6374

2008-08-28 09:45

jreese


Details Diff
Fix 0008882: Serve secure Gravatar images when using HTTPS.

git-svn-id: http://mantisbt.svn.sourceforge.net/svnroot/mantisbt/branches/BRANCH_1_1_0@5529 <a class="text" href="/?p=mantisbt.git;a=object;h=f5dc347c">f5dc347c</a>-c33d-0410-90a0-b07cc1902cb9
Affected Issues
0008882
mod - core/user_api.php Diff File

MantisBT: master 241f91d5

2008-08-28 09:48

jreese


Details Diff
Fix 0008882: Serve secure Gravatar images when using HTTPS.

git-svn-id: http://mantisbt.svn.sourceforge.net/svnroot/mantisbt/trunk@5530 <a class="text" href="/?p=mantisbt.git;a=object;h=f5dc347c">f5dc347c</a>-c33d-0410-90a0-b07cc1902cb9
Affected Issues
0008882
mod - core/user_api.php Diff File