Package: websvn
Severity: serious
Tags: security patch

Hi,

James Clawson reported:

"Arbitrary files with a known path can be accessed in websvn by committing a
symlink to a repository and then downloading the file (using the download
link).

An attacker must have write access to the repo, and the download option must
have been enabled in the websvn config file.

Example:
- Create a symlink to /etc/passwd and commit it to the repo.
- Access websvn and download the file.
- The downloaded file will be the web server's /etc/passwd (i.e. the symlink is
  resolved on the web server).

This will also work with symlinks to directories, but dlmode=zip must be added
to the download link manually. Zip must be installed manually to be able to
download directories."


I've assigned CVE-2013-6892 to this issue. Please mention it in the changelog
when fixing the issue.

I've created attached patch which solves the bug.

Cheers,
Thijs
diff -ur oud/dl.php nieuw/dl.php
--- oud/dl.php	2015-01-18 16:03:30.688791512 +0100
+++ nieuw/dl.php	2015-01-18 16:27:00.950897749 +0100
@@ -137,6 +137,18 @@
 		exit(0);
 	}
 
+	// For security reasons, disallow direct downloads of filenames that
+	// are a symlink, since they may be a symlink to anywhere (/etc/passwd)
+	// Deciding whether the symlink is relative and legal within the
+	// repository would be nice but seems to error prone at this moment.
+	if ( is_link($tempDir.DIRECTORY_SEPARATOR.$archiveName) ) {
+		header('HTTP/1.x 500 Internal Server Error', true, 500);
+		error_log('to be downloaded file is symlink, aborting: '.$archiveName);
+		print 'Download of symlinks disallowed: "'.xml_entities($archiveName).'".';
+		removeDirectory($tempDir);
+		exit(0);
+	}
+
 	// Set timestamp of exported directory (and subdirectories) to timestamp of
 	// the revision so every archive of a given revision has the same timestamp.
 	$revDate = $logEntry->date;
@@ -180,7 +192,7 @@
 		$downloadMimeType = 'application/x-zip';
 		$downloadArchive .= '.zip';
 		// Create zip file
-		$cmd = $config->zip.' -r '.quote($downloadArchive).' '.quote($archiveName);
+		$cmd = $config->zip.' --symlinks -r '.quote($downloadArchive).' '.quote($archiveName);
 		execCommand($cmd, $retcode);
 		if ($retcode != 0) {
 			error_log('Unable to call zip command: '.$cmd);

Reply via email to