CVE-2017-15278: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-Site Scripting (XSS) was discovered in TeamPass before 2.1.27.9. The vulnerability exists due to insufficient filtration of data (in /sources/folders.queries.php). An attacker could execute arbitrary HTML and script code in a browser in the context of the vulnerable website.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2017-10-12T08:29Z
Repository: https://github.com/nilsteampassnet/TeamPass
Language: PHP
Files changed: changelog.md, folders.load.php, folders.php, includes/language/arabic.php, includes/language/bulgarian.php, includes/language/catalan.php, includes/language/chinese.php, includes/language/czech.php, includes/language/dutch.php, includes/language/english.php, includes/language/estonian.php, includes/language/french.php, includes/language/german.php, includes/language/greek.php, includes/language/hungarian.php, includes/language/italian.php, includes/language/japanese.php, includes/language/norwegian.php, includes/language/polish.php, includes/language/portuguese.php, includes/language/portuguese_br.php, includes/language/romanian.php, includes/language/russian.php, includes/language/spanish.php, includes/language/swedish.php, includes/language/turkish.php, includes/language/ukrainian.php, includes/language/vietnamese.php, items.load.php, profile.php, sources/folders.queries.php, sources/items.queries.php, sources/main.functions.php
Commit date: 2017-10-11 20:16:04 +0200
Commit message: 2.1.27

Fixed "PW copy to clipboard" log unconsistency in specific case
Improved the possibility to define the access level on Roles when creating new folder

Diff: diff --git a/changelog.md b/changelog.md
index 45bf1a91f..4618f174c 100755
--- a/changelog.md
+++ b/changelog.md
@@ -7,12 +7,14 @@
  	> a user could potentially act on Items he should not have access to
  Securized script.backup.php by adding a security key
  Fixed some other security failures (credit to ​security at Amossys)
  Improved security regarding uploading files
  Fixed issue while restoring DB from administration page
+ Fixed "PW copy to clipboard" log unconsistency in specific case
  Improved / Fixed administration task for encrypting/decrypting files
  Improved security regarding item history display
+ Improved the possibility to define the access level on Roles when creating new folder
  Added filter in Roles
  New: confirm deletion of attachment
  #1956 Warning appears on Category and API pages in admin mode
  #1947 Dependency & array update in install checks
  #1945 Cannot delete items
diff --git a/folders.load.php b/folders.load.php
index 4127be0df..1d5c28171 100644
--- a/folders.load.php
+++ b/folders.load.php
@@ -18,10 +18,11 @@ if (!isset($_SESSION['CPM']) || $_SESSION['CPM'] != 1) {
 ?>
 
 <script type="text/javascript">
 //<![CDATA[
 $(function() {
+    $("#span_new_rep_roles").hide();
 
     //Launch the datatables pluggin
     var tableFolders = $("#t_folders").dataTable({
         "order": [[ 1, "asc" ]],
         "ordering": false,
@@ -59,11 +60,11 @@ $(function() {
         title: "<?php echo $LANG['add_new_group']; ?>",
         open: function(event, ui) {
             $("#new_folder_wait").hide();
 
             //empty dialogbox
-            $("#div_add_group input, #div_add_group select").val("");
+            $("#div_add_group input, #div_add_group select, #new_rep_roles").val("");
             $("#add_node_renewal_period").val("0");
             $("#folder_block_modif, #folder_block_creation").val("0");
             $("#parent_id").val("na");
         },
         buttons: {
@@ -87,11 +88,12 @@ $(function() {
                             "title":$('#ajouter_groupe_titre').val().replace(/"/g,'&quot;') ,
                             "complexity": $('#new_rep_complexite').val().replace(/"/g,'&quot;'),
                             "parent_id": $('#parent_id').val().replace(/"/g,'&quot;') ,
                             "renewal_period": $('#add_node_renewal_period').val().replace(/"/g,'&quot;') ,
                             "block_creation": $("#folder_block_creation").val() ,
-                            "block_modif": $("#folder_block_modif").val()
+                            "block_modif": $("#folder_block_modif").val(),
+                            "access_level": $("#new_rep_roles").val()
                         };
 
                         //send query
                         $.post(
                             "sources/folders.queries.php",
@@ -332,10 +334,18 @@ $(function() {
     });
 
     $("#click_refresh_folders_list").click(function() {
         tableFolders.api().ajax.reload();
     });
+
+    $("#parent_id").change(function() {
+        if ($(this).val() === "0") {
+            $("#span_new_rep_roles").show();
+        } else {
+            $("#span_new_rep_roles").hide();
+        }
+    })
 });
 
 
 /**
  *
diff --git a/folders.php b/folders.php
index 0f3473273..decc631c3 100644
--- a/folders.php
+++ b/folders.php
@@ -114,37 +114,46 @@ echo '
 /* Form Add a folder */
 echo '
 <div id="div_add_group" style="display:none;">
     <div id="addgroup_show_error" style="text-align:center;margin:2px;display:none;" class="ui-state-error ui-corner-all"></div>
 
-    <label for="ajouter_groupe_titre" class="label_cpm">'.$LANG['group_title'].'</label>
+    <label for="ajouter_groupe_titre" class="label_cpm">'.addslashes($LANG['group_title']).'</label>
     <input type="text" id="ajouter_groupe_titre" class="input_text text ui-widget-content ui-corner-all" />
 
     <label for="parent_id" class="label_cpm">'.addslashes($LANG['group_parent']).'</label>
     <select id="parent_id" class="input_text text ui-widget-content ui-corner-all">
         '.$droplist.'
     </select>
 
-    <label for="new_rep_complexite" class="label_cpm">'.$LANG['complex_asked'].'</label>
+    <label for="new_rep_complexite" class="label_cpm">'.addslashes($LANG['complex_asked']).'</label>
     <select id="new_rep_complexite" class="input_text text ui-widget-content ui-corner-all">';
 foreach ($SETTINGS_EXT['pwComplexity'] as $complex) {
     echo '<option value="'.$complex[0].'">'.$complex[1].'</option>';
 }
 echo '
     </select>
 
-    <label for="add_node_renewal_period" class="label_cpm">'.$LANG['group_pw_duration'].'</label>
+    <span id="span_new_rep_roles">
+    <label for="new_rep_roles" class="label_cpm">'.addslashes($LANG['access_level_for_roles']).'</label>
+    <select id="new_rep_roles" class="input_text text ui-widget-content ui-corner-all">
+        <option value="">'.$LANG['no_access'].'</option>
+        <option value="R">'.$LANG['read'].'</option>
+        <option value="W">'.$LANG['write'].'</option>
+    </select>
+    </span>
+
+    <label for="add_node_renewal_period" class="label_cpm">'.addslashes($LANG['group_pw_duration']).'</label>
     <input type="text" id="add_node_renewal_period" value="0" class="input_text text ui-widget-content ui-corner-all" />
 
-    <label for="folder_block_creation" class="">'.$LANG['auth_creation_without_complexity'].'</label>
+    <label for="folder_block_creation" class="">'.addslashes($LANG['auth_creation_without_complexity']).'</label>
     <select id="folder_block_creation" class="ui-widget-content ui-corner-all">
         <option value="0">'.$LANG['no'].'</option>
         <option value="1">'.$LANG['yes'].'</option>
     </select>
 
     <div style="margin-top:10px;">
-        <label for="folder_block_modif">'.$LANG['auth_modification_without_complexity'].'</label>
+        <label for="folder_block_modif">'.addslashes($LANG['auth_modification_without_complexity']).'</label>
         <select id="folder_block_modif" class="ui-widget-content ui-corner-all">
             <option value="0">'.$LANG['no'].'</option>
             <option value="1">'.$LANG['yes'].'</option>
         </select>
     </div>
diff --git a/includes/language/arabic.php b/includes/language/arabic.php
index 1d9fb77e5..368e1367e 100644
--- a/includes/language/arabic.php
+++ b/includes/language/arabic.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/bulgarian.php b/includes/language/bulgarian.php
index d3786f80b..6bf1303bc 100644
--- a/includes/language/bulgarian.php
+++ b/includes/language/bulgarian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/catalan.php b/includes/language/catalan.php
index 0889632d3..61a8ea84a 100644
--- a/includes/language/catalan.php
+++ b/includes/language/catalan.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/chinese.php b/includes/language/chinese.php
index 334eb09e3..c5f83235e 100644
--- a/includes/language/chinese.php
+++ b/includes/language/chinese.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/czech.php b/includes/language/czech.php
index ac7de46ab..58b2798f1 100644
--- a/includes/language/czech.php
+++ b/includes/language/czech.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/dutch.php b/includes/language/dutch.php
index 5c474700d..dbb8b2b7c 100644
--- a/includes/language/dutch.php
+++ b/includes/language/dutch.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/english.php b/includes/language/english.php
index 4d1a5b133..b5a2c1062 100644
--- a/includes/language/english.php
+++ b/includes/language/english.php
@@ -1,6 +1,6 @@
-<?php 
+<?php
 /**
  *
  * @file          english.php
  * @author        Nils Laumaillé
  * @version       2.1.27
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'user_ga_code' => 'Email Google Authentication to user',
     'send_ga_code' => 'Set and email Google Authentication code',
     'error_no_email' => 'This user has no email address set!',
diff --git a/includes/language/estonian.php b/includes/language/estonian.php
index adea12611..c8fc29cf3 100644
--- a/includes/language/estonian.php
+++ b/includes/language/estonian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/french.php b/includes/language/french.php
index a04ef6b73..c296e9737 100644
--- a/includes/language/french.php
+++ b/includes/language/french.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Droit associé des Roles',
     'user_ga_code' => 'Envoyer le code Google Authenticator à l\'utilisateur par email',
     'send_ga_code' => 'Google Authenticator pour l\'utilisateur',
     'error_no_email' => 'Cet utilisateur n\'a pas de courriel de défini !',
     'error_no_user' => 'Aucun utilisateur trouvé !',
     'email_ga_subject' => 'Votre code Google Authenticator pour Teampass',
diff --git a/includes/language/german.php b/includes/language/german.php
index ac4f2600c..a2cf5429c 100644
--- a/includes/language/german.php
+++ b/includes/language/german.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/greek.php b/includes/language/greek.php
index 4c337650c..e0acf60ec 100644
--- a/includes/language/greek.php
+++ b/includes/language/greek.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/hungarian.php b/includes/language/hungarian.php
index 3720ee97a..8b340236b 100644
--- a/includes/language/hungarian.php
+++ b/includes/language/hungarian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/italian.php b/includes/language/italian.php
index 3927d266d..78d0bda2b 100644
--- a/includes/language/italian.php
+++ b/includes/language/italian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/japanese.php b/includes/language/japanese.php
index dd7634e2e..ae7d53029 100644
--- a/includes/language/japanese.php
+++ b/includes/language/japanese.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/norwegian.php b/includes/language/norwegian.php
index f4a705757..bc4eb1f20 100644
--- a/includes/language/norwegian.php
+++ b/includes/language/norwegian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/polish.php b/includes/language/polish.php
index e68b60301..6621de9d6 100644
--- a/includes/language/polish.php
+++ b/includes/language/polish.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/portuguese.php b/includes/language/portuguese.php
index 7cc01a841..e466eabd4 100644
--- a/includes/language/portuguese.php
+++ b/includes/language/portuguese.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/portuguese_br.php b/includes/language/portuguese_br.php
index 51a4d0cb1..be6e461b1 100644
--- a/includes/language/portuguese_br.php
+++ b/includes/language/portuguese_br.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/romanian.php b/includes/language/romanian.php
index af2c5faf0..71e2a0537 100644
--- a/includes/language/romanian.php
+++ b/includes/language/romanian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/russian.php b/includes/language/russian.php
index c0d718fa3..a1c8a3ad5 100644
--- a/includes/language/russian.php
+++ b/includes/language/russian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/spanish.php b/includes/language/spanish.php
index 3a60282e4..5c10f45fc 100644
--- a/includes/language/spanish.php
+++ b/includes/language/spanish.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/swedish.php b/includes/language/swedish.php
index 48fb35bcb..22cbfce6f 100644
--- a/includes/language/swedish.php
+++ b/includes/language/swedish.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/turkish.php b/includes/language/turkish.php
index 68308706d..bf4780308 100644
--- a/includes/language/turkish.php
+++ b/includes/language/turkish.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/ukrainian.php b/includes/language/ukrainian.php
index 92b3a5dd4..a65cd2330 100644
--- a/includes/language/ukrainian.php
+++ b/includes/language/ukrainian.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/includes/language/vietnamese.php b/includes/language/vietnamese.php
index 0a51eade4..09469ba37 100644
--- a/includes/language/vietnamese.php
+++ b/includes/language/vietnamese.php
@@ -12,10 +12,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  */
 global $LANG;
 $LANG = array (
+    'access_level_for_roles' => 'Associated access for Roles',
     'admin_script_backup_secret' => 'Passkey for backup execution',
     'admin_script_backup_secret_tip' => 'The backup passkey needs to be provided to start the backup. It has to be added a key parameter to script.backup.php. Example:scripts.backup.php?key=your_passkey',
     'text' => 'Text',
     'masked' => 'Masked',
     'type' => 'Type',
diff --git a/items.load.php b/items.load.php
index 351a98126..a1a92bf6d 100755
--- a/items.load.php
+++ b/items.load.php
@@ -3930,19 +3930,21 @@ var showPwd = function(){
 }
 
 /*
 * permits to save
 */
-function itemLog(log_case)
+function itemLog(log_case, item_id)
 {
+    console.log("> "+item_id);
+    item_id = item_id || $('#id_item').val();
     $.post(
         "sources/items.logs.php",
         {
             type        : log_case,
-            id_item     : $('#id_item').val(),
+            id_item     : item_id,
             folder_id   : $('#hid_cat').val(),
-        hid_label   : $('#hid_label').val(),
+            hid_label   : $('#hid_label').val(),
             key         : "<?php echo $_SESSION['key']; ?>"
         }
     );
 }
 
@@ -4023,11 +4025,11 @@ function proceed_list_update(stop_proceeding)
         });
 
         var clipboard = new Clipboard('.mini_pw');
         clipboard.on('success', function(e) {
             $("#message_box").html("<?php echo addslashes($LANG['pw_copied_clipboard']); ?>").show().fadeOut(1000);
-            itemLog("item_password_copied");
+            itemLog("item_password_copied", e.trigger.dataset.clipboardId);
             e.clearSelection();
         });
 
         $(".tip").tooltipster({multiple: true});
         $(".mini_login, .mini_pw").css("cursor", "pointer");
diff --git a/profile.php b/profile.php
index 622fbca3f..1d366eb32 100644
--- a/profile.php
+++ b/profile.php
@@ -90,10 +90,20 @@ foreach (timezone_identifiers_list() as $zone) {
 $rows = DB::query("SELECT label FROM ".prefix_table("languages")." ORDER BY label ASC");
 foreach ($rows as $record) {
     $arraFlags[$record['label']] = $record['label'];
 }
 
+// Prepare Headers
+header('Access-Control-Allow-Origin: *');
+echo '
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+    <head>
+        <title>User Profile</title>
+    </head>
+<body>';
+
 echo '
 <input type="hidden" id="profile_user_token" value="" />
 <table style="margin-left:7px;">
     <tr>
         <td rowspan="4" style="width:94px">
@@ -715,5 +725,7 @@ function changePersonalSaltKey(credentials, ids, nb_total)
             }
         }
     );
 }
 </script>
+</body>
+</html>
diff --git a/sources/folders.queries.php b/sources/folders.queries.php
index 32f61e021..e2ac66e7a 100644
--- a/sources/folders.queries.php
+++ b/sources/folders.queries.php
@@ -436,10 +436,23 @@ if (null !== $post_newtitle) {
             //Prepare variables
             $title = filter_var(htmlspecialchars_decode($dataReceived['title']), FILTER_SANITIZE_STRING);
             $complexity = htmlspecialchars_decode($dataReceived['complexity']);
             $parentId = htmlspecialchars_decode($dataReceived['parent_id']);
             $renewalPeriod = htmlspecialchars_decode($dataReceived['renewal_period']);
+            if ($parentId === "0") {
+                if (isset($dataReceived['access_level']) === true) {
+                    $access_level_by_role = filter_var(htmlspecialchars_decode($dataReceived['access_level']), FILTER_SANITIZE_STRING);
+                } else {
+                    if ($_SESSION['user_manager'] === "1") {
+                        $access_level_by_role = "W";
+                    } else {
+                        $access_level_by_role = "";
+                    }
+                }
+            } else {
+                $access_level_by_role = "";
+            }
 
             //Check if title doesn't contains html codes
             if (preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $title, $out)) {
                 echo '[ { "error" : "error_html_codes"} ]';
                 break;
@@ -542,50 +555,56 @@ if (null !== $post_newtitle) {
 
                     // rebuild tree
                     $tree = new Tree\NestedTree\NestedTree(prefix_table("nested_tree"), 'id', 'parent_id', 'title');
                     $tree->rebuild();
 
-                    if ($isPersonal !== 1
-                        && isset($SETTINGS['subfolder_rights_as_parent'])
-                        && $SETTINGS['subfolder_rights_as_parent'] === 1
-                        || ($isPersonal !== 1 && $parentId === "0")
-                    ) {
+                    // Add right to see this folder
+                    if ($_SESSION['is_admin'] === "1" || $_SESSION['user_manager'] === "1") {
                         //Get user's rights
                         identifyUserRights(
-                            array_push($_SESSION['groupes_visibles'], $newId),
+                            $_SESSION['groupes_visibles'],
                             implode(";", $_SESSION['groupes_interdits']),
                             $_SESSION['is_admin'],
-                            $_SESSION['fonction_id']
+                            is_array($_SESSION['fonction_id']) === true ? implode(";", $_SESSION['fonction_id']) : $_SESSION['fonction_id']
                         );
+                    }
 
+                    if ($isPersonal !== 1
+                        && $parentId === "0"
+                    ) {
                         //add access to this new folder
                         foreach (explode(';', $_SESSION['fonction_id']) as $role) {
-                            if (!empty($role)) {
+                            if (empty($role) === false && empty($access_level_by_role) === false) {
                                 DB::insert(
                                     prefix_table("roles_values"),
                                     array(
                                         'role_id' => $role,
                                         'folder_id' => $newId,
-                                        'type' => "W"
+                                        'type' => $access_level_by_role
                                     )
                                 );
                             }
                         }
                     }
 
-                    //If it is a subfolder, then give access to it for all roles that allows the parent folder
-                    $rows = DB::query("SELECT role_id, type FROM ".prefix_table("roles_values")." WHERE folder_id = %i", $parentId);
-                    foreach ($rows as $record) {
-                        //add access to this subfolder
-                        DB::insert(
-                            prefix_table("roles_values"),
-                            array(
-                                'role_id' => $record['role_id'],
-                                'folder_id' => $newId,
-                                'type' => $record['type']
-                            )
-                        );
+
+                    if (isset($SETTINGS['subfolder_rights_as_parent']) === true
+                        && $SETTINGS['subfolder_rights_as_parent'] === "1"
+                    ) {
+                        //If it is a subfolder, then give access to it for all roles that allows the parent folder
+                        $rows = DB::query("SELECT role_id, type FROM ".prefix_table("roles_values")." WHERE folder_id = %i", $parentId);
+                        foreach ($rows as $record) {
+                            //add access to this subfolder
+                            DB::insert(
+                                prefix_table("roles_values"),
+                                array(
+                                    'role_id' => $record['role_id'],
+                                    'folder_id' => $newId,
+                                    'type' => $record['type']
+                                )
+                            );
+                        }
                     }
 
                     // if parent folder has Custom Fields Categories then add to this child one too
                     $rows = DB::query("SELECT id_category FROM ".prefix_table("categories_folders")." WHERE id_folder = %i", $parentId);
                     foreach ($rows as $record) {
diff --git a/sources/items.queries.php b/sources/items.queries.php
index d10d13cb7..f29ef12b1 100644
--- a/sources/items.queries.php
+++ b/sources/items.queries.php
@@ -2693,11 +2693,11 @@ if (null !== $post_type) {
                             if ($displayItem === true) {
                                 if (empty($record['login']) === false) {
                                     $new_line .= '<i class="fa fa-sm fa-user mi-black mini_login" data-clipboard-text="'.strtr($record['login'], '"', "&quot;").'" title="'.$LANG['item_menu_copy_login'].'"></i>&nbsp;';
                                 }
                                 if (empty($pw) === false) {
-                                    $new_line .= '<i class="fa fa-sm fa-lock mi-black mini_pw" data-clipboard-text="'.strtr($pw, '"', "&quot;").'" title="'.$LANG['item_menu_copy_pw'].'"></i>&nbsp;';
+                                    $new_line .= '<i class="fa fa-sm fa-lock mi-black mini_pw" data-clipboard-text="'.strtr($pw, '"', "&quot;").'" title="'.$LANG['item_menu_copy_pw'].'" data-clipboard-id="'.$record['id'].'"></i>&nbsp;';
                                 }
                             }
                         }
                         // Prepare make Favorite small icon
                         $new_line .= '<span id="quick_icon_fav_'.$record['id'].'" title="Manage Favorite" class="cursor tip">';
diff --git a/sources/main.functions.php b/sources/main.functions.php
index 28b90e44e..a86f2f552 100644
--- a/sources/main.functions.php
+++ b/sources/main.functions.php
@@ -508,10 +508,13 @@ function defuse_return_decrypted($value)
  * @return string
  */
 function trimElement($chaine, $element)
 {
     if (!empty($chaine)) {
+        if (is_array($chaine) === true) {
+            $chaine = implode(";", $chaine);
+        }
         $chaine = trim($chaine);
         if (substr($chaine, 0, 1) == $element) {
             $chaine = substr($chaine, 1);
         }
         if (substr($chaine, strlen($chaine) - 1, 1) == $element) {
@@ -656,11 +659,11 @@ function identifyUserRights($groupesVisiblesUser, $groupesInterditsUser, $isAdmi
         $_SESSION['groupes_interdits'] = array();
         $_SESSION['personal_visible_groups'] = array();
         $_SESSION['read_only_folders'] = array();
         $_SESSION['fonction_id'] = $idFonctions;
         $groupesInterdits = array();
-        if (!is_array($groupesInterditsUser)) {
+        if (is_array($groupesInterditsUser) === false) {
             $groupesInterditsUser = explode(';', trimElement($groupesInterditsUser, ";"));
         }
         if (!empty($groupesInterditsUser) && count($groupesInterditsUser) > 0) {
             $groupesInterdits = $groupesInterditsUser;
         }

Vulnerable code:             $("#div_add_group input, #div_add_group select").val("");
                            "block_modif": $("#folder_block_modif").val()
    <label for="ajouter_groupe_titre" class="label_cpm">'.$LANG['group_title'].'</label>
    <label for="new_rep_complexite" class="label_cpm">'.$LANG['complex_asked'].'</label>
    <label for="add_node_renewal_period" class="label_cpm">'.$LANG['group_pw_duration'].'</label>
    <label for="folder_block_creation" class="">'.$LANG['auth_creation_without_complexity'].'</label>
        <label for="folder_block_modif">'.$LANG['auth_modification_without_complexity'].'</label>
<?php 
function itemLog(log_case)
            id_item     : $('#id_item').val(),
        hid_label   : $('#hid_label').val(),
            itemLog("item_password_copied");
                    if ($isPersonal !== 1
                        && isset($SETTINGS['subfolder_rights_as_parent'])
                        && $SETTINGS['subfolder_rights_as_parent'] === 1
                        || ($isPersonal !== 1 && $parentId === "0")
                    ) {
                            array_push($_SESSION['groupes_visibles'], $newId),
                            $_SESSION['fonction_id']
                            if (!empty($role)) {
                                        'type' => "W"
                    //If it is a subfolder, then give access to it for all roles that allows the parent folder
                    $rows = DB::query("SELECT role_id, type FROM ".prefix_table("roles_values")." WHERE folder_id = %i", $parentId);
                    foreach ($rows as $record) {
                        //add access to this subfolder
                        DB::insert(
                            prefix_table("roles_values"),
                            array(
                                'role_id' => $record['role_id'],
                                'folder_id' => $newId,
                                'type' => $record['type']
                            )
                        );
                                    $new_line .= '<i class="fa fa-sm fa-lock mi-black mini_pw" data-clipboard-text="'.strtr($pw, '"', "&quot;").'" title="'.$LANG['item_menu_copy_pw'].'"></i>&nbsp;';
        if (!is_array($groupesInterditsUser)) {
Fixed code:  Fixed "PW copy to clipboard" log unconsistency in specific case
 Improved the possibility to define the access level on Roles when creating new folder
    $("#span_new_rep_roles").hide();
            $("#div_add_group input, #div_add_group select, #new_rep_roles").val("");
                            "block_modif": $("#folder_block_modif").val(),
                            "access_level": $("#new_rep_roles").val()

    $("#parent_id").change(function() {
        if ($(this).val() === "0") {
            $("#span_new_rep_roles").show();
        } else {
            $("#span_new_rep_roles").hide();
        }
    })
    <label for="ajouter_groupe_titre" class="label_cpm">'.addslashes($LANG['group_title']).'</label>
    <label for="new_rep_complexite" class="label_cpm">'.addslashes($LANG['complex_asked']).'</label>
    <span id="span_new_rep_roles">
    <label for="new_rep_roles" class="label_cpm">'.addslashes($LANG['access_level_for_roles']).'</label>
    <select id="new_rep_roles" class="input_text text ui-widget-content ui-corner-all">
        <option value="">'.$LANG['no_access'].'</option>
        <option value="R">'.$LANG['read'].'</option>
        <option value="W">'.$LANG['write'].'</option>
    </select>
    </span>

    <label for="add_node_renewal_period" class="label_cpm">'.addslashes($LANG['group_pw_duration']).'</label>
    <label for="folder_block_creation" class="">'.addslashes($LANG['auth_creation_without_complexity']).'</label>
        <label for="folder_block_modif">'.addslashes($LANG['auth_modification_without_complexity']).'</label>
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
<?php
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Droit associé des Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
    'access_level_for_roles' => 'Associated access for Roles',
function itemLog(log_case, item_id)
    console.log("> "+item_id);
    item_id = item_id || $('#id_item').val();
            id_item     : item_id,
            hid_label   : $('#hid_label').val(),
            itemLog("item_password_copied", e.trigger.dataset.clipboardId);
// Prepare Headers
header('Access-Control-Allow-Origin: *');
echo '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>User Profile</title>
    </head>
<body>';

</body>
</html>
            if ($parentId === "0") {
                if (isset($dataReceived['access_level']) === true) {
                    $access_level_by_role = filter_var(htmlspecialchars_decode($dataReceived['access_level']), FILTER_SANITIZE_STRING);
                } else {
                    if ($_SESSION['user_manager'] === "1") {
                        $access_level_by_role = "W";
                    } else {
                        $access_level_by_role = "";
                    }
                }
            } else {
                $access_level_by_role = "";
            }
                    // Add right to see this folder
                    if ($_SESSION['is_admin'] === "1" || $_SESSION['user_manager'] === "1") {
                            $_SESSION['groupes_visibles'],
                            is_array($_SESSION['fonction_id']) === true ? implode(";", $_SESSION['fonction_id']) : $_SESSION['fonction_id']
                    }
                    if ($isPersonal !== 1
                        && $parentId === "0"
                    ) {
                            if (empty($role) === false && empty($access_level_by_role) === false) {
                                        'type' => $access_level_by_role

                    if (isset($SETTINGS['subfolder_rights_as_parent']) === true
                        && $SETTINGS['subfolder_rights_as_parent'] === "1"
                    ) {
                        //If it is a subfolder, then give access to it for all roles that allows the parent folder
                        $rows = DB::query("SELECT role_id, type FROM ".prefix_table("roles_values")." WHERE folder_id = %i", $parentId);
                        foreach ($rows as $record) {
                            //add access to this subfolder
                            DB::insert(
                                prefix_table("roles_values"),
                                array(
                                    'role_id' => $record['role_id'],
                                    'folder_id' => $newId,
                                    'type' => $record['type']
                                )
                            );
                        }
                                    $new_line .= '<i class="fa fa-sm fa-lock mi-black mini_pw" data-clipboard-text="'.strtr($pw, '"', "&quot;").'" title="'.$LANG['item_menu_copy_pw'].'" data-clipboard-id="'.$record['id'].'"></i>&nbsp;';
        if (is_array($chaine) === true) {
            $chaine = implode(";", $chaine);
        }
        if (is_array($groupesInterditsUser) === false) {