From: Joey Hess <id@joeyh.name>
Date: Mon, 18 Jun 2018 17:40:50 -0400
X-Dgit-Generated: 6.20170101-1+deb9u2 139539615478c1f618525715bef184d450b38558
Subject: block url downloads by default

git-annex will refuse to download content from the web, to prevent
accidental exposure of data on private webservers on localhost and the
LAN. This can be overridden with the
annex.security.allowed-http-addresses setting.

This is the simplest possible fix for the security hole. A better fix
has been developed for newer versions of git-annex but would be a lot of
work to backport, and perhaps too big a diff.

There are several sets of git-annex users who will be impacted
in different ways by this:

* Users who have a git-annex repository but don't use the web special
  remote. Unaffected.

* Users who have a git-annex repository that is for private use only.
  They will have to read enough docs to find the setting to allow
  git annex addurl to work again.

* Users who have a git-annex repositry that is shared with people they
  don't fully trust.
  They will not be able to use the web special remote with this version
  of git-annex. They'll have to upgrade.

The S3, glacier, and webdav special remotes are still allowed to
download from the web. There are other potential attacks involving the
web server they connect to redirecting to a local private web server,
and tricking them from downloading content from it which then leaks back
to the attacker. Those attacks are not addressed here, but they also
seem fairly unlikely. Further analysis is needed; preliminary analysis
of glacier-cli, for example, suggests it does not follow redirects and
so is not vulnerable to such attacks.

---

--- git-annex-6.20170101.orig/Annex/Quvi.hs
+++ git-annex-6.20170101/Annex/Quvi.hs
@@ -11,8 +11,8 @@ module Annex.Quvi where
 
 import Annex.Common
 import qualified Annex
+import Annex.Url
 import Utility.Quvi
-import Utility.Url
 
 withQuviOptions :: forall a. Query a -> [QuviParams] -> URLString -> Annex a
 withQuviOptions a ps url = do
@@ -21,7 +21,14 @@ withQuviOptions a ps url = do
 	liftIO $ a v (concatMap (\mkp -> mkp v) ps ++ opts) url
 
 quviSupported :: URLString -> Annex Bool
-quviSupported u = liftIO . flip supported u =<< quviVersion
+quviSupported u = ifM httpAddressesUnlimited
+	( liftIO . flip supported u =<< quviVersion
+	-- Don't allow any url schemes to be used when
+	-- there's a limit on the allowed addresses, because
+	-- there is no way to prevent quvi from
+	-- redirecting to any address.
+	, return False
+	)
 
 quviVersion :: Annex QuviVersion
 quviVersion = go =<< Annex.getState Annex.quviversion
--- git-annex-6.20170101.orig/Annex/Url.hs
+++ git-annex-6.20170101/Annex/Url.hs
@@ -11,6 +11,7 @@ module Annex.Url (
 	withUrlOptions,
 	getUrlOptions,
 	getUserAgent,
+	httpAddressesUnlimited,
 ) where
 
 import Annex.Common
@@ -18,6 +19,8 @@ import qualified Annex
 import Utility.Url as U
 import qualified Build.SysConfig as SysConfig
 
+import qualified Data.Set as S
+
 defaultUserAgent :: U.UserAgent
 defaultUserAgent = "git-annex/" ++ SysConfig.packageversion
 
@@ -30,7 +33,7 @@ getUrlOptions = mkUrlOptions
 	<$> getUserAgent
 	<*> headers
 	<*> options
-	<*> (annexAllowedUrlSchemes <$> Annex.getGitConfig)
+	<*> urlschemes
   where
 	headers = do
 		v <- annexHttpHeadersCommand <$> Annex.getGitConfig
@@ -38,6 +41,18 @@ getUrlOptions = mkUrlOptions
 			Just cmd -> lines <$> liftIO (readProcess "sh" ["-c", cmd])
 			Nothing -> annexHttpHeaders <$> Annex.getGitConfig
 	options = map Param . annexWebOptions <$> Annex.getGitConfig
+	urlschemes = ifM httpAddressesUnlimited
+		( annexAllowedUrlSchemes <$> Annex.getGitConfig
+		-- Don't allow any url schemes to be used when
+		-- there's a limit on the allowed addresses, because
+		-- there is no way to prevent curl or wget from
+		-- redirecting to any address.
+		, pure S.empty
+		)
+
+httpAddressesUnlimited :: Annex Bool
+httpAddressesUnlimited =
+	("all" == ) . annexAllowedHttpAddresses <$> Annex.getGitConfig
 
 withUrlOptions :: (U.UrlOptions -> IO a) -> Annex a
 withUrlOptions a = liftIO . a =<< getUrlOptions
--- git-annex-6.20170101.orig/NEWS
+++ git-annex-6.20170101/NEWS
@@ -4,6 +4,12 @@ git-annex (6.20170101-1+deb9u2) stretch-
   URL schemes by default. You can enable other URL schemes, at your own risk,
   using annex.security.allowed-url-schemes.
 
+  A related security fix prevents git-annex from downloading content from
+  the web. This can be overridden with the
+  annex.security.allowed-http-addresses setting.
+  (The S3, glacier, and webdav special remotes are still allowed to
+  download from the web.)
+
   The annex.web-download-command configuration has been removed,
   use annex.web-options instead.
 
--- git-annex-6.20170101.orig/doc/git-annex.mdwn
+++ git-annex-6.20170101/doc/git-annex.mdwn
@@ -1253,6 +1253,21 @@ Here are all the supported configuration
   Some special remotes support their own domain-specific URL
   schemes; those are not affected by this configuration setting.
 
+* `annex.security.allowed-http-addresses`
+
+  By default, this version of git-annex refuses to download the content of
+  annexed files from the web. Newer versions of git-annex allow downloading
+  from the web, but only when the web server is not on a private IP address.
+
+  To relax this security check and allow getting annexed files from
+  anywhere on the web, set this to "all".
+  
+  Think very carefully before changing this; there are security
+  implications. Anyone who can get a commit into your git-annex repository
+  could `git annex addurl` an url on a private http server, possibly
+  causing it to be downloaded into your repository and transferred to
+  other remotes, exposing its content.
+
 * `annex.secure-erase-command`
 
   This can be set to a command that should be run whenever git-annex
