RoyAalekh commited on
Commit
ea9b5e5
·
1 Parent(s): 8bcd80c

security: Remove all hardcoded passwords from codebase and documentation

Browse files

- Require all passwords to be set via environment variables
- Application will not start without required environment variables
- Remove all hardcoded passwords from auth.py, login.html, and SECURITY.md
- Add proper error handling for missing environment variables
- Update login page to only fill username, not password
- Remove development fallback passwords for security compliance
- Update documentation to emphasize security requirements

BREAKING CHANGE: Environment variables AALEKH_PASSWORD, ADMIN_PASSWORD,
ISHITA_PASSWORD, and JEEB_PASSWORD are now required for app startup.

Files changed (3) hide show
  1. SECURITY.md +81 -0
  2. auth.py +16 -4
  3. static/login.html +13 -9
SECURITY.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TreeTrack Security Configuration
2
+
3
+ ## Environment Variables for Authentication
4
+
5
+ For security reasons, user passwords should be configured via environment variables instead of being hardcoded. The application supports the following environment variables:
6
+
7
+ ### Required Environment Variables
8
+
9
+ Set these in your HuggingFace Space settings or deployment environment:
10
+
11
+ ```bash
12
+ # Administrator passwords
13
+ AALEKH_PASSWORD=your_secure_password_here
14
+ ADMIN_PASSWORD=your_secure_admin_password_here
15
+
16
+ # User passwords
17
+ ISHITA_PASSWORD=your_secure_password_here
18
+ JEEB_PASSWORD=your_secure_password_here
19
+ ```
20
+
21
+ ### Security Requirement
22
+
23
+ ⚠️ **Critical**: All user passwords MUST be configured via environment variables. The application will not start without these environment variables being set.
24
+
25
+ No default passwords are provided for security reasons.
26
+
27
+ ## How to Set Environment Variables in HuggingFace Spaces
28
+
29
+ 1. Go to your HuggingFace Space settings
30
+ 2. Navigate to the "Variables and secrets" section
31
+ 3. Add the following environment variables:
32
+ - `AALEKH_PASSWORD` - Set a strong password for Aalekh (admin)
33
+ - `ADMIN_PASSWORD` - Set a strong password for admin account
34
+ - `ISHITA_PASSWORD` - Set a strong password for Ishita
35
+ - `JEEB_PASSWORD` - Set a strong password for Jeeb
36
+ 4. Restart your space to apply the changes
37
+
38
+ ## Password Security Best Practices
39
+
40
+ - Use strong passwords with at least 12 characters
41
+ - Include uppercase, lowercase, numbers, and special characters
42
+ - Avoid common words or personal information
43
+ - Use unique passwords for each account
44
+ - Consider using a password manager to generate secure passwords
45
+
46
+ ## User Roles and Permissions
47
+
48
+ - **aalekh** & **admin**: Full administrative access (can edit/delete any tree)
49
+ - **ishita** & **jeeb**: Researcher access (can add trees and edit their own trees)
50
+
51
+ ## Session Security
52
+
53
+ - Sessions expire after 8 hours of inactivity
54
+ - Automatic cleanup of expired sessions
55
+ - Secure session tokens generated using cryptographically secure random numbers
56
+ - All API endpoints require authentication
57
+
58
+ ## Additional Security Measures
59
+
60
+ 1. **HTTPS**: Always use HTTPS in production
61
+ 2. **Rate Limiting**: Consider implementing rate limiting for login attempts
62
+ 3. **Audit Logging**: All authentication events are logged
63
+ 4. **Password Hashing**: Passwords are hashed using PBKDF2 with 100,000 iterations
64
+ 5. **Session Management**: Secure session token generation and validation
65
+
66
+ ## Development vs Production
67
+
68
+ ### Development (Current Setup)
69
+ - Default passwords are used if environment variables are not set
70
+ - Suitable for testing and development environments
71
+
72
+ ### Production Recommendations
73
+ - Always set secure passwords via environment variables
74
+ - Use a proper database for user management
75
+ - Implement additional security features like 2FA
76
+ - Regular security audits and password rotation
77
+ - Use proper logging and monitoring
78
+
79
+ ---
80
+
81
+ Remember: Security is an ongoing process. Regularly review and update your security practices!
auth.py CHANGED
@@ -5,6 +5,7 @@ Simple session-based authentication with predefined users
5
 
6
  import hashlib
7
  import secrets
 
8
  from typing import Dict, Optional, Any
9
  from datetime import datetime, timedelta
10
  import logging
@@ -16,11 +17,22 @@ class AuthManager:
16
  self.sessions: Dict[str, Dict[str, Any]] = {}
17
  self.session_timeout = timedelta(hours=8) # 8-hour session timeout
18
 
 
 
 
 
 
 
 
 
 
 
 
19
  # Predefined user accounts (in production, use a database)
20
  self.users = {
21
  # Administrator account
22
  "aalekh": {
23
- "password_hash": self._hash_password("aalekh@maptrees"),
24
  "role": "admin",
25
  "full_name": "Aalekh",
26
  "permissions": ["read", "write", "delete", "admin"]
@@ -28,7 +40,7 @@ class AuthManager:
28
 
29
  # System account (for admin use)
30
  "admin": {
31
- "password_hash": self._hash_password("admin@maptrees"),
32
  "role": "admin",
33
  "full_name": "System Administrator",
34
  "permissions": ["read", "write", "delete", "admin"]
@@ -36,14 +48,14 @@ class AuthManager:
36
 
37
  # User accounts
38
  "ishita": {
39
- "password_hash": self._hash_password("ishita@maptrees"),
40
  "role": "researcher",
41
  "full_name": "Ishita",
42
  "permissions": ["read", "write", "edit_own"]
43
  },
44
 
45
  "jeeb": {
46
- "password_hash": self._hash_password("jeeb@maptrees"),
47
  "role": "researcher",
48
  "full_name": "Jeeb",
49
  "permissions": ["read", "write", "edit_own"]
 
5
 
6
  import hashlib
7
  import secrets
8
+ import os
9
  from typing import Dict, Optional, Any
10
  from datetime import datetime, timedelta
11
  import logging
 
17
  self.sessions: Dict[str, Dict[str, Any]] = {}
18
  self.session_timeout = timedelta(hours=8) # 8-hour session timeout
19
 
20
+ # Get passwords from environment variables (required for security)
21
+ aalekh_password = os.getenv('AALEKH_PASSWORD')
22
+ admin_password = os.getenv('ADMIN_PASSWORD')
23
+ ishita_password = os.getenv('ISHITA_PASSWORD')
24
+ jeeb_password = os.getenv('JEEB_PASSWORD')
25
+
26
+ # Check if all required passwords are set
27
+ if not all([aalekh_password, admin_password, ishita_password, jeeb_password]):
28
+ logger.error("Missing required password environment variables. Please set AALEKH_PASSWORD, ADMIN_PASSWORD, ISHITA_PASSWORD, and JEEB_PASSWORD.")
29
+ raise ValueError("Authentication passwords must be configured via environment variables")
30
+
31
  # Predefined user accounts (in production, use a database)
32
  self.users = {
33
  # Administrator account
34
  "aalekh": {
35
+ "password_hash": self._hash_password(aalekh_password),
36
  "role": "admin",
37
  "full_name": "Aalekh",
38
  "permissions": ["read", "write", "delete", "admin"]
 
40
 
41
  # System account (for admin use)
42
  "admin": {
43
+ "password_hash": self._hash_password(admin_password),
44
  "role": "admin",
45
  "full_name": "System Administrator",
46
  "permissions": ["read", "write", "delete", "admin"]
 
48
 
49
  # User accounts
50
  "ishita": {
51
+ "password_hash": self._hash_password(ishita_password),
52
  "role": "researcher",
53
  "full_name": "Ishita",
54
  "permissions": ["read", "write", "edit_own"]
55
  },
56
 
57
  "jeeb": {
58
+ "password_hash": self._hash_password(jeeb_password),
59
  "role": "researcher",
60
  "full_name": "Jeeb",
61
  "permissions": ["read", "write", "edit_own"]
static/login.html CHANGED
@@ -272,23 +272,26 @@
272
  <div class="demo-accounts">
273
  <div class="demo-title">🔐 Available Accounts</div>
274
  <div class="account-list">
275
- <div class="account-item" onclick="fillCredentials('aalekh', 'aalekh@maptrees')">
276
  <div class="account-role">Aalekh (Admin)</div>
277
  <div class="account-username">Full system access</div>
278
  </div>
279
- <div class="account-item" onclick="fillCredentials('admin', 'admin@maptrees')">
280
  <div class="account-role">System Admin</div>
281
  <div class="account-username">Administrative access</div>
282
  </div>
283
- <div class="account-item" onclick="fillCredentials('ishita', 'ishita@maptrees')">
284
  <div class="account-role">Ishita</div>
285
  <div class="account-username">Tree research & documentation</div>
286
  </div>
287
- <div class="account-item" onclick="fillCredentials('jeeb', 'jeeb@maptrees')">
288
  <div class="account-role">Jeeb</div>
289
  <div class="account-username">Tree research & documentation</div>
290
  </div>
291
  </div>
 
 
 
292
  </div>
293
 
294
  <div class="footer">
@@ -297,9 +300,10 @@
297
  </div>
298
 
299
  <script>
300
- function fillCredentials(username, password) {
301
  document.getElementById('username').value = username;
302
- document.getElementById('password').value = password;
 
303
 
304
  // Add visual feedback
305
  const accountItems = document.querySelectorAll('.account-item');
@@ -400,11 +404,11 @@
400
  }
401
  });
402
 
403
- // Auto-fill demo credentials on page load for development
404
  document.addEventListener('DOMContentLoaded', () => {
405
- // Auto-select ishita account for easy testing
406
  setTimeout(() => {
407
- fillCredentials('ishita', 'ishita@maptrees');
408
  }, 1000);
409
  });
410
  </script>
 
272
  <div class="demo-accounts">
273
  <div class="demo-title">🔐 Available Accounts</div>
274
  <div class="account-list">
275
+ <div class="account-item" onclick="fillCredentials('aalekh')">
276
  <div class="account-role">Aalekh (Admin)</div>
277
  <div class="account-username">Full system access</div>
278
  </div>
279
+ <div class="account-item" onclick="fillCredentials('admin')">
280
  <div class="account-role">System Admin</div>
281
  <div class="account-username">Administrative access</div>
282
  </div>
283
+ <div class="account-item" onclick="fillCredentials('ishita')">
284
  <div class="account-role">Ishita</div>
285
  <div class="account-username">Tree research & documentation</div>
286
  </div>
287
+ <div class="account-item" onclick="fillCredentials('jeeb')">
288
  <div class="account-role">Jeeb</div>
289
  <div class="account-username">Tree research & documentation</div>
290
  </div>
291
  </div>
292
+ <div style="margin-top: 1rem; padding: 0.75rem; background: rgba(255, 193, 7, 0.1); border: 1px solid rgba(255, 193, 7, 0.3); border-radius: 8px; font-size: 0.75rem; color: #856404;">
293
+ ℹ️ <strong>Note:</strong> Contact your administrator for login credentials. Default passwords are only for development/testing.
294
+ </div>
295
  </div>
296
 
297
  <div class="footer">
 
300
  </div>
301
 
302
  <script>
303
+ function fillCredentials(username) {
304
  document.getElementById('username').value = username;
305
+ document.getElementById('password').value = '';
306
+ document.getElementById('password').focus();
307
 
308
  // Add visual feedback
309
  const accountItems = document.querySelectorAll('.account-item');
 
404
  }
405
  });
406
 
407
+ // Auto-fill demo username on page load for development
408
  document.addEventListener('DOMContentLoaded', () => {
409
+ // Auto-select ishita account for easy testing (password still needs to be entered)
410
  setTimeout(() => {
411
+ fillCredentials('ishita');
412
  }, 1000);
413
  });
414
  </script>