Bladeren bron

More robust application of access permissions (#5062)

* More robust application of access permissions
We were in particular missing directory traversal `+X` in our current recommendations.
Extracted to own shell script so it can easily be invoked.
Update access permissions in Docker to account to be more robust.
#fix https://github.com/FreshRSS/FreshRSS/discussions/5037

* Minor simplification

* Restrict mkdir permissions
Default mkdir permissions are 0777, which is not good for security, so downgrade to 0770.
Alexandre Alapetite 3 jaren geleden
bovenliggende
commit
e899e4edd9

+ 5 - 6
Docker/entrypoint.sh

@@ -7,8 +7,6 @@ find /etc/php*/ -type f -name php.ini -exec sed -r -i "\\#^;?date.timezone#s#^.*
 find /etc/php*/ -type f -name php.ini -exec sed -r -i "\\#^;?post_max_size#s#^.*#post_max_size = 32M#" {} \;
 find /etc/php*/ -type f -name php.ini -exec sed -r -i "\\#^;?post_max_size#s#^.*#post_max_size = 32M#" {} \;
 find /etc/php*/ -type f -name php.ini -exec sed -r -i "\\#^;?upload_max_filesize#s#^.*#upload_max_filesize = 32M#" {} \;
 find /etc/php*/ -type f -name php.ini -exec sed -r -i "\\#^;?upload_max_filesize#s#^.*#upload_max_filesize = 32M#" {} \;
 
 
-php -f ./cli/prepare.php >/dev/null
-
 if [ -n "$LISTEN" ]; then
 if [ -n "$LISTEN" ]; then
 	find /etc/apache2/ -type f -name FreshRSS.Apache.conf -exec sed -r -i "\\#^Listen#s#^.*#Listen $LISTEN#" {} \;
 	find /etc/apache2/ -type f -name FreshRSS.Apache.conf -exec sed -r -i "\\#^Listen#s#^.*#Listen $LISTEN#" {} \;
 fi
 fi
@@ -24,6 +22,10 @@ if [ -n "$CRON_MIN" ]; then
 		-r "s#^[^ ]+ #$CRON_MIN #" | crontab -
 		-r "s#^[^ ]+ #$CRON_MIN #" | crontab -
 fi
 fi
 
 
+./cli/access-permissions.sh
+
+php -f ./cli/prepare.php >/dev/null
+
 if [ -n "$FRESHRSS_INSTALL" ]; then
 if [ -n "$FRESHRSS_INSTALL" ]; then
 	# shellcheck disable=SC2046
 	# shellcheck disable=SC2046
 	php -f ./cli/do-install.php -- \
 	php -f ./cli/do-install.php -- \
@@ -57,9 +59,6 @@ if [ -n "$FRESHRSS_USER" ]; then
 	fi
 	fi
 fi
 fi
 
 
-chown -R :www-data .
-chmod -R g+r .
-chmod -R g+w ./data/
-chmod g+x ./extensions/
+./cli/access-permissions.sh
 
 
 exec "$@"
 exec "$@"

+ 2 - 2
README.fr.md

@@ -113,7 +113,7 @@ cd FreshRSS
 sudo git checkout $(git describe --tags --abbrev=0)
 sudo git checkout $(git describe --tags --abbrev=0)
 
 
 # Mettre les droits d’accès pour le serveur Web
 # Mettre les droits d’accès pour le serveur Web
-sudo chown -R :www-data . && sudo chmod -R g+r . && sudo chmod -R g+w ./data/
+sudo cli/access-permissions.sh
 # Si vous souhaitez permettre les mises à jour par l’interface Web
 # Si vous souhaitez permettre les mises à jour par l’interface Web
 sudo chmod -R g+w .
 sudo chmod -R g+w .
 
 
@@ -126,7 +126,7 @@ sudo ln -s /usr/share/FreshRSS/p /var/www/html/FreshRSS
 # Mettre à jour FreshRSS vers une nouvelle version par git
 # Mettre à jour FreshRSS vers une nouvelle version par git
 cd /usr/share/FreshRSS
 cd /usr/share/FreshRSS
 sudo git pull
 sudo git pull
-sudo chown -R :www-data . && sudo chmod -R g+r . && sudo chmod -R g+w ./data/
+sudo cli/access-permissions.sh
 ```
 ```
 
 
 Voir la [documentation de la ligne de commande](cli/README.md) pour plus de détails.
 Voir la [documentation de la ligne de commande](cli/README.md) pour plus de détails.

+ 1 - 1
app/Controllers/userController.php

@@ -242,7 +242,7 @@ class FreshRSS_user_Controller extends FreshRSS_ActionController {
 		}
 		}
 		if ($ok) {
 		if ($ok) {
 			if (!is_dir($homeDir)) {
 			if (!is_dir($homeDir)) {
-				mkdir($homeDir);
+				mkdir($homeDir, 0770, true);
 			}
 			}
 			$ok &= (file_put_contents($configPath, "<?php\n return " . var_export($userConfig, true) . ';') !== false);
 			$ok &= (file_put_contents($configPath, "<?php\n return " . var_export($userConfig, true) . ';') !== false);
 		}
 		}

+ 2 - 2
app/Models/Feed.php

@@ -979,14 +979,14 @@ class FreshRSS_Feed extends Minz_Model {
 					$key = $hubJson['key'];	//To renew our lease
 					$key = $hubJson['key'];	//To renew our lease
 				}
 				}
 			} else {
 			} else {
-				@mkdir($path, 0777, true);
+				@mkdir($path, 0770, true);
 				$key = sha1($path . FreshRSS_Context::$system_conf->salt);
 				$key = sha1($path . FreshRSS_Context::$system_conf->salt);
 				$hubJson = array(
 				$hubJson = array(
 					'hub' => $this->hubUrl,
 					'hub' => $this->hubUrl,
 					'key' => $key,
 					'key' => $key,
 				);
 				);
 				file_put_contents($hubFilename, json_encode($hubJson));
 				file_put_contents($hubFilename, json_encode($hubJson));
-				@mkdir(PSHB_PATH . '/keys/');
+				@mkdir(PSHB_PATH . '/keys/', 0770, true);
 				file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', $this->selfUrl);
 				file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', $this->selfUrl);
 				$text = 'WebSub prepared for ' . $this->url;
 				$text = 'WebSub prepared for ' . $this->url;
 				Minz_Log::debug($text);
 				Minz_Log::debug($text);

+ 1 - 3
cli/README.md

@@ -18,9 +18,7 @@ In any case, when you are done with a series of commands, you should re-apply th
 
 
 ```sh
 ```sh
 cd /usr/share/FreshRSS
 cd /usr/share/FreshRSS
-sudo chown -R :www-data .
-sudo chmod -R g+r .
-sudo chmod -R g+w ./data/
+sudo cli/access-permissions.sh
 ```
 ```
 
 
 
 

+ 1 - 1
cli/_cli.php

@@ -44,7 +44,7 @@ function cliInitUser($username) {
 
 
 function accessRights() {
 function accessRights() {
 	echo 'ℹ️ Remember to re-apply the appropriate access rights, such as:',
 	echo 'ℹ️ Remember to re-apply the appropriate access rights, such as:',
-		"\t", 'sudo chown -R :www-data . && sudo chmod -R g+r . && sudo chmod -R g+w ./data/', "\n";
+		"\t", 'sudo cli/access-permissions.sh', "\n";
 }
 }
 
 
 function done($ok = true) {
 function done($ok = true) {

+ 19 - 0
cli/access-permissions.sh

@@ -0,0 +1,19 @@
+#!/bin/sh
+# Apply access permissions
+
+if [ ! -f './constants.php' ] || [ ! -d './cli/' ]; then
+	echo >&2 '⛔ It does not look like a FreshRSS directory; exiting!'
+	exit 2
+fi
+
+if [ "$(id -u)" -ne 0 ]; then
+	echo >&2 '⛔ Applying access permissions require running as root or sudo!'
+	exit 3
+fi
+
+# Based on group access
+chown -R :www-data .
+# Read files, and directory traversal
+chmod -R g+rX .
+# Write access
+chmod -R g+w ./data/

+ 1 - 1
cli/i18n/I18nFile.php

@@ -27,7 +27,7 @@ class I18nFile {
 		foreach ($i18n as $language => $file) {
 		foreach ($i18n as $language => $file) {
 			$dir = I18N_PATH . DIRECTORY_SEPARATOR . $language;
 			$dir = I18N_PATH . DIRECTORY_SEPARATOR . $language;
 			if (!file_exists($dir)) {
 			if (!file_exists($dir)) {
-				mkdir($dir);
+				mkdir($dir, 0770, true);
 			}
 			}
 			foreach ($file as $name => $content) {
 			foreach ($file as $name => $content) {
 				$filename = $dir . DIRECTORY_SEPARATOR . $name;
 				$filename = $dir . DIRECTORY_SEPARATOR . $name;

+ 1 - 8
docs/en/admins/06_LinuxInstall.md

@@ -81,14 +81,7 @@ Change to the new FreshRSS directory, and set the permissions so that your Web s
 
 
 ```sh
 ```sh
 cd FreshRSS
 cd FreshRSS
-chown -R :www-data .
-sudo chmod -R g+r .
-```
-
-We’ll also need to allow the data folder to be written to, like so:
-
-```sh
-chmod -R g+w ./data/
+sudo cli/access-permissions.sh
 ```
 ```
 
 
 Optional: If you would like to allow updates from the Web interface, set write permissions
 Optional: If you would like to allow updates from the Web interface, set write permissions

+ 2 - 2
docs/en/admins/07_LinuxUpdate.md

@@ -64,7 +64,7 @@ If your local user doesn’t have write access to the FreshRSS folder, use a sud
 
 
 6. Re-set correct permissions so that your web server can access the files
 6. Re-set correct permissions so that your web server can access the files
 	```sh
 	```sh
-	chown -R :www-data . && chmod -R g+r . && chmod -R g+w ./data/
+	cli/access-permissions.sh
 	```
 	```
 
 
 ## Using the Zip archive
 ## Using the Zip archive
@@ -91,7 +91,7 @@ If your local user doesn’t have write access to the FreshRSS folder, use a sud
 
 
 5. Re-set permissions
 5. Re-set permissions
 	```sh
 	```sh
-	chown -R :www-data . && chmod -R g+r . && chmod -R g+w ./data/
+	cli/access-permissions.sh
 	```
 	```
 
 
 6. Clean up the FreshRSS directory by deleting the downloaded zip and the temporary directory
 6. Clean up the FreshRSS directory by deleting the downloaded zip and the temporary directory

+ 1 - 1
lib/Minz/Migrator.php

@@ -55,7 +55,7 @@ class Minz_Migrator
 		}
 		}
 
 
 		$lock_path = $applied_migrations_path . '.lock';
 		$lock_path = $applied_migrations_path . '.lock';
-		if (!@mkdir($lock_path)) {
+		if (!@mkdir($lock_path, 0770, true)) {
 			// Someone is probably already executing the migrations (the folder
 			// Someone is probably already executing the migrations (the folder
 			// already exists).
 			// already exists).
 			// We should probably return something else, but we don't want the
 			// We should probably return something else, but we don't want the