Browse Source

Account recovery still broken (server sessions?)

biotorrents 4 years ago
parent
commit
443a75e6db

+ 1
- 1
classes/config.template View File

421
 # Misc stuff like generic reusable snippets
421
 # Misc stuff like generic reusable snippets
422
 # Example of a variable using heredoc syntax
422
 # Example of a variable using heredoc syntax
423
 ENV::setPub(
423
 ENV::setPub(
424
-    'PASSWORD_ADVICE',
424
+    'PW_ADVICE',
425
     <<<HTML
425
     <<<HTML
426
     <p>
426
     <p>
427
       Any password 15 characters or longer is accepted, but a strong password
427
       Any password 15 characters or longer is accepted, but a strong password

+ 44
- 0
classes/input.class.php View File

1
+<?php
2
+declare(strict_types=1);
3
+
4
+/**
5
+ * Input class
6
+ * 
7
+ * An attempt to normalize and secure form inputs.
8
+ */
9
+
10
+class Input {
11
+
12
+    /**
13
+     * passphrase
14
+     */
15
+    function passphrase(
16
+        string $Name = 'password',
17
+        string $ID = 'password',
18
+        string $Placeholder = 'Passphrase',
19
+        bool $Advice = false) {
20
+        $ENV = ENV::go();
21
+
22
+        # Input validation
23
+        if (!is_string($Name) || empty($Name)) {
24
+            error("Expected non-empty string, got \$Name = $Name in Input::passphrase.");
25
+        }
26
+
27
+        if (!empty($Advice) && $Advice !== true || $Advice !== false) {
28
+            error("Expected true|false, got \$Advice = $Advice in Input::passphrase.");
29
+        }
30
+
31
+        $Field = <<<HTML
32
+        <input type="password" name="$Name" id="$ID" placeholder="$Placeholder"
33
+          minlength="$ENV->PW_MIN" maxlength="$ENV->PW_MAX"
34
+          class="inputtext" autocomplete="off" required="required" />
35
+HTML;
36
+
37
+if ($Advice) {
38
+    return $Field . $ENV->PW_ADVICE;
39
+} else {
40
+    return $Field;
41
+}
42
+
43
+    }
44
+}

+ 2
- 1
classes/mysql.class.php View File

270
                 $this->Database,
270
                 $this->Database,
271
                 $this->Port,
271
                 $this->Port,
272
                 $this->Socket,
272
                 $this->Socket,
273
+                # Needed for self-signed certs
273
                 MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT
274
                 MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT
274
             );
275
             );
275
 
276
 
289
     public function prepare_query($Query, &...$BindVars)
290
     public function prepare_query($Query, &...$BindVars)
290
     {
291
     {
291
         $this->connect();
292
         $this->connect();
292
-
293
         $this->StatementID = mysqli_prepare($this->LinkID, $Query);
293
         $this->StatementID = mysqli_prepare($this->LinkID, $Query);
294
+
294
         if (!empty($BindVars)) {
295
         if (!empty($BindVars)) {
295
             $Types = '';
296
             $Types = '';
296
             $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
297
             $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];

+ 0
- 3
sections/login/index.php View File

1
 <?php
1
 <?php
2
 #declare(strict_types=1);
2
 #declare(strict_types=1);
3
 
3
 
4
-# Unsure if require_once is needed here
5
-require_once 'classes/env.class.php';
6
 $ENV = ENV::go();
4
 $ENV = ENV::go();
7
 
5
 
8
 /*-- todo ---------------------------//
6
 /*-- todo ---------------------------//
33
 $TwoFA = new TwoFactorAuth($ENV->SITE_NAME);
31
 $TwoFA = new TwoFactorAuth($ENV->SITE_NAME);
34
 $U2F = new u2f\U2F('https://'.SITE_DOMAIN);
32
 $U2F = new u2f\U2F('https://'.SITE_DOMAIN);
35
 
33
 
36
-# todo: Test strict equality very gently here
37
 if (array_key_exists('action', $_GET) && $_GET['action'] === 'disabled') {
34
 if (array_key_exists('action', $_GET) && $_GET['action'] === 'disabled') {
38
     require('disabled.php');
35
     require('disabled.php');
39
     error();
36
     error();

+ 1
- 2
sections/login/login.php View File

47
 
47
 
48
     <tr>
48
     <tr>
49
       <td>
49
       <td>
50
-        <input type="password" minlength="15" name="password" id="password" class="inputtext" required="required"
51
-          maxlength="307200" pattern=".{15,307200}" placeholder="Password" autocomplete="current-password" />
50
+        <?= Input::passphrase() ?>
52
       </td>
51
       </td>
53
 
52
 
54
       <td>
53
       <td>

+ 7
- 4
sections/login/recover_step2.php View File

9
 if (empty($PassWasReset)) {
9
 if (empty($PassWasReset)) {
10
     if (!empty($Err)) { ?>
10
     if (!empty($Err)) { ?>
11
 <strong class="important_text"><?=display_str($Err)?></strong><br /><br />
11
 <strong class="important_text"><?=display_str($Err)?></strong><br /><br />
12
-<?php
13
-}
14
-    
15
-    echo $ENV->PASSWORD_ADVICE; ?>
12
+<?php } ?>
16
 
13
 
17
 <form class="auth_form" name="recovery" id="recoverform" method="post" action="" onsubmit="return formVal();">
14
 <form class="auth_form" name="recovery" id="recoverform" method="post" action="" onsubmit="return formVal();">
18
   <input type="hidden" name="key"
15
   <input type="hidden" name="key"
25
       </td>
22
       </td>
26
 
23
 
27
       <td>
24
       <td>
25
+        <?= Input::passphrase($Name = 'password', $ID='new_pass_1', $Placeholder = 'New passphrase') ?>
26
+        <!--
28
         <input type="password" minlength="15" name="password" id="new_pass_1" class="inputtext" size="40"
27
         <input type="password" minlength="15" name="password" id="new_pass_1" class="inputtext" size="40"
29
           placeholder="New Password" pattern=".{15,307200}" required style="width: 250px !important;">
28
           placeholder="New Password" pattern=".{15,307200}" required style="width: 250px !important;">
29
+        -->
30
       </td>
30
       </td>
31
     </tr>
31
     </tr>
32
 
32
 
35
         <strong id="pass_match"></strong>
35
         <strong id="pass_match"></strong>
36
       </td>
36
       </td>
37
       <td>
37
       <td>
38
+        <?= Input::passphrase($Name = 'verifypassword', $ID='new_pass_2', $Placeholder = 'Confirm passphrase') ?>
39
+        <!--
38
         <input type="password" minlength="15" name="verifypassword" id="new_pass_2" class="inputtext" size="40"
40
         <input type="password" minlength="15" name="verifypassword" id="new_pass_2" class="inputtext" size="40"
39
           placeholder="Confirm Password" pattern=".{15,307200}" required style="width: 250px !important;">
41
           placeholder="Confirm Password" pattern=".{15,307200}" required style="width: 250px !important;">
42
+        -->
40
       </td>
43
       </td>
41
     </tr>
44
     </tr>
42
 
45
 

+ 1
- 1
sections/register/step1.php View File

65
         <input type="password" minlength="15" name="confirm_password" id="new_pass_2" class="inputtext"
65
         <input type="password" minlength="15" name="confirm_password" id="new_pass_2" class="inputtext"
66
           placeholder="Confirm Password" />
66
           placeholder="Confirm Password" />
67
         <strong id="pass_match"></strong>
67
         <strong id="pass_match"></strong>
68
-        <?= $ENV->PASSWORD_ADVICE ?>
68
+        <?= $ENV->PW_ADVICE ?>
69
       </td>
69
       </td>
70
     </tr>
70
     </tr>
71
 
71
 

+ 16
- 15
sections/torrents/download.php View File

67
 
67
 
68
 $Info = $Cache->get_value('torrent_download_'.$TorrentID);
68
 $Info = $Cache->get_value('torrent_download_'.$TorrentID);
69
 if (!is_array($Info) || !array_key_exists('PlainArtists', $Info) || empty($Info[10])) {
69
 if (!is_array($Info) || !array_key_exists('PlainArtists', $Info) || empty($Info[10])) {
70
-    $DB->query("
70
+    $DB->prepare_query("
71
       SELECT
71
       SELECT
72
-        t.Media,
73
-        t.Version,
74
-        t.Codec,
75
-        tg.Year,
76
-        tg.ID AS GroupID,
77
-        COALESCE(NULLIF(tg.Name,''), NULLIF(tg.Title2,''), tg.NameJP) AS Name,
78
-        tg.WikiImage,
79
-        tg.CategoryID,
80
-        t.Size,
81
-        t.FreeTorrent,
82
-        HEX(t.info_hash)
83
-      FROM torrents AS t
84
-        INNER JOIN torrents_group AS tg ON tg.ID = t.GroupID
85
-      WHERE t.ID = '".db_string($TorrentID)."'");
72
+        t.`Media`,
73
+        t.`Version`,
74
+        t.`Codec`,
75
+        tg.`year`,
76
+        tg.`id` AS GroupID,
77
+        COALESCE(NULLIF(tg.`title`,''), NULLIF(tg.`subject`,''), tg.`object`) AS Name,
78
+        tg.`picture`,
79
+        tg.`category_id`,
80
+        t.`Size`,
81
+        t.`FreeTorrent`,
82
+        HEX(t.`info_hash`)
83
+      FROM `torrents` AS t
84
+        INNER JOIN `torrents_group` AS tg ON tg.`id` = t.`GroupID`
85
+      WHERE t.`ID` = '".db_string($TorrentID)."'");
86
+      $DB->exec_prepared_query();
86
 
87
 
87
     if (!$DB->has_results()) {
88
     if (!$DB->has_results()) {
88
         error(404);
89
         error(404);

+ 4
- 1
sections/upload/upload_handle.php View File

793
 //******************************************************************************//
793
 //******************************************************************************//
794
 //--------------- Write torrent file -------------------------------------------//
794
 //--------------- Write torrent file -------------------------------------------//
795
 
795
 
796
-file_put_contents(TORRENT_STORE.$TorrentID.'.torrent', $Tor->encode());
796
+$FileName = "$ENV->TORRENT_STORE/$TorrentID.torrent";
797
+file_put_contents($FileName, $Tor->encode());
798
+chmod($FileName, 0400);
799
+
797
 Misc::write_log("Torrent $TorrentID ($LogName) (".number_format($TotalSize / (1024 * 1024), 2).' MB) was uploaded by ' . $LoggedUser['Username']);
800
 Misc::write_log("Torrent $TorrentID ($LogName) (".number_format($TotalSize / (1024 * 1024), 2).' MB) was uploaded by ' . $LoggedUser['Username']);
798
 Torrents::write_group_log($GroupID, $TorrentID, $LoggedUser['ID'], 'uploaded ('.number_format($TotalSize / (1024 * 1024), 2).' MB)', 0);
801
 Torrents::write_group_log($GroupID, $TorrentID, $LoggedUser['ID'], 'uploaded ('.number_format($TotalSize / (1024 * 1024), 2).' MB)', 0);
799
 
802
 

+ 1
- 1
sections/user/edit.php View File

1398
             </div>
1398
             </div>
1399
 
1399
 
1400
             <p class="setting_description">
1400
             <p class="setting_description">
1401
-              <?= $ENV->PASSWORD_ADVICE ?>
1401
+              <?= $ENV->PW_ADVICE ?>
1402
             </p>
1402
             </p>
1403
           </td>
1403
           </td>
1404
         </tr>
1404
         </tr>

+ 35
- 1
static/functions/password_validate.js View File

57
 
57
 
58
   });
58
   });
59
 
59
 
60
+
61
+  /**
62
+   * calculateComplexity
63
+   */
60
   function calculateComplexity(password) {
64
   function calculateComplexity(password) {
61
     var length = password.length;
65
     var length = password.length;
62
     var username;
66
     var username;
103
     }
107
     }
104
   }
108
   }
105
 
109
 
110
+
111
+  /**
112
+   * isStrongPassword
113
+   * 
114
+   * $ENV-PW_MIN is still harcoded here.
115
+   */
106
   function isStrongPassword(password) {
116
   function isStrongPassword(password) {
107
-    return /(?=^.{6,}$).*$/.test(password);
117
+    return /(?=^.{15,}$).*$/.test(password);
108
   }
118
   }
109
 
119
 
120
+
121
+  /**
122
+   * checkMatching
123
+   */
110
   function checkMatching(password1, password2) {
124
   function checkMatching(password1, password2) {
111
     if (password2.length > 0) {
125
     if (password2.length > 0) {
112
       if (password1 == password2 && getStrong() == true) {
126
       if (password1 == password2 && getStrong() == true) {
124
     }
138
     }
125
   }
139
   }
126
 
140
 
141
+
142
+  /**
143
+   * getStrong
144
+   */
127
   function getStrong() {
145
   function getStrong() {
128
     return $("#pass_strength").text() == "Strong";
146
     return $("#pass_strength").text() == "Strong";
129
   }
147
   }
130
 
148
 
149
+
150
+  /**
151
+   * setStatus
152
+   */
131
   function setStatus(strength) {
153
   function setStatus(strength) {
132
     if (strength == WEAK) {
154
     if (strength == WEAK) {
133
       disableSubmit();
155
       disableSubmit();
164
     }
186
     }
165
   }
187
   }
166
 
188
 
189
+
190
+  /**
191
+   * disableSubmit
192
+   */
167
   function disableSubmit() {
193
   function disableSubmit() {
168
     $('input[type="submit"]').attr('disabled', 'disabled');
194
     $('input[type="submit"]').attr('disabled', 'disabled');
169
   }
195
   }
170
 
196
 
197
+
198
+  /**
199
+   * enableSubmit
200
+   */
171
   function enableSubmit() {
201
   function enableSubmit() {
172
     $('input[type="submit"]').removeAttr('disabled');
202
     $('input[type="submit"]').removeAttr('disabled');
173
   }
203
   }
174
 
204
 
205
+
206
+  /**
207
+   * isUserPage
208
+   */
175
   function isUserPage() {
209
   function isUserPage() {
176
     return window.location.pathname.indexOf(USER_PATH) != -1;
210
     return window.location.pathname.indexOf(USER_PATH) != -1;
177
   }
211
   }

Loading…
Cancel
Save