This commit is contained in:
Copilot 2025-07-15 18:25:25 +00:00 committed by GitHub
commit 6edce60969
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 874 additions and 2 deletions

2
.gitignore vendored
View file

@ -1 +1,3 @@
/build/
.gradle/
.idea/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

View file

@ -1,2 +1,2 @@
#Sun Feb 16 16:27:39 CET 2025
gradle.version=8.8
#Tue Jul 15 18:19:16 UTC 2025
gradle.version=8.14.3

Binary file not shown.

141
security-demo/README.md Normal file
View file

@ -0,0 +1,141 @@
# Security Demonstration Website
⚠️ **WARNING: This website contains intentional security vulnerabilities for educational purposes only. DO NOT use any of these patterns in production applications!**
## Overview
This demonstration website shows common security vulnerabilities that can compromise login credentials and user data. It's designed to educate developers about what NOT to do when building web applications.
## How to Use
1. Open `index.html` in a web browser
2. Use the demo credentials: `admin` / `password123`
3. Explore the dashboard to see various vulnerabilities in action
4. Open browser developer tools (F12) to see console logs exposing sensitive data
## Security Vulnerabilities Demonstrated
### 1. Plain Text Password Storage
- **Location**: `login.js` and localStorage
- **Issue**: Passwords stored in plain text in localStorage and JavaScript variables
- **Real-world impact**: Anyone with access to the device can see passwords
### 2. Client-Side Authentication
- **Location**: `login.js`
- **Issue**: Authentication logic runs entirely in the browser
- **Real-world impact**: Can be easily bypassed by modifying JavaScript
### 3. XSS (Cross-Site Scripting) Vulnerabilities
- **Location**: `dashboard.js` - command execution function
- **Issue**: User input directly inserted into HTML using innerHTML
- **Demo**: Try entering `<script>alert('XSS')</script>` in the command field
- **Real-world impact**: Attackers can execute malicious scripts
### 4. SQL Injection Simulation
- **Location**: `dashboard.js` - user search function
- **Issue**: User input directly concatenated into SQL query
- **Demo**: Try searching for `' OR 1=1 --`
- **Real-world impact**: Database compromise, data theft
### 5. Information Disclosure
- **Location**: Throughout the application
- **Issues**:
- Credentials exposed in console logs
- Session data visible in browser
- Error messages reveal system information
- Debug functions exposed globally
### 6. No Brute Force Protection
- **Location**: `login.js`
- **Issue**: No rate limiting or account lockout
- **Real-world impact**: Attackers can try unlimited password combinations
### 7. Insecure Data Transmission
- **Location**: URL parameters in dashboard redirect
- **Issue**: Credentials passed in URL parameters
- **Real-world impact**: Passwords visible in browser history, server logs
### 8. CSRF (Cross-Site Request Forgery) Vulnerability
- **Location**: `dashboard.js` - admin functions
- **Issue**: No CSRF tokens or verification
- **Real-world impact**: Malicious sites can perform actions on behalf of users
### 9. Eval() Injection
- **Location**: `dashboard.js` - command execution
- **Issue**: Using eval() with user input
- **Demo**: Try command `eval:alert('Code injection')`
- **Real-world impact**: Arbitrary code execution
### 10. Exposed Debug Functions
- **Location**: `dashboard.js` - global window functions
- **Issue**: Administrative functions accessible via browser console
- **Demo**: Try `window.adminFunctions.deleteAllUsers()` in console
## Educational Points
### What Developers Should Do Instead:
1. **Password Security**:
- Hash passwords with strong algorithms (bcrypt, Argon2)
- Never store plain text passwords
- Use secure session management
2. **Authentication**:
- Implement server-side authentication
- Use secure session tokens
- Implement proper logout procedures
3. **Input Validation**:
- Sanitize all user inputs
- Use parameterized queries
- Implement proper output encoding
4. **Access Controls**:
- Implement rate limiting
- Use CSRF tokens
- Require proper authorization for admin functions
5. **Data Protection**:
- Use HTTPS for all communications
- Implement proper error handling
- Don't expose sensitive data in logs or console
## Testing the Vulnerabilities
### XSS Testing:
1. Go to the dashboard
2. In the "Execute Command" field, enter: `<img src=x onerror=alert('XSS')>`
3. Click Execute to see the XSS in action
### SQL Injection Testing:
1. In the "User Search" field, enter: `admin'; DROP TABLE users; --`
2. See how the vulnerable query construction is exposed
### Authentication Bypass:
1. Open browser console (F12)
2. Type: `window.bypassLogin()` and press Enter
3. See how client-side authentication can be bypassed
### Session Data Exposure:
1. Open browser console
2. Type: `localStorage` to see stored credentials
3. Type: `window.currentSessionData` to see exposed session information
## Files Structure
- `index.html` - Login page with vulnerable authentication
- `dashboard.html` - Admin dashboard with multiple vulnerabilities
- `styles.css` - Styling for the demonstration
- `login.js` - Vulnerable login logic
- `dashboard.js` - Vulnerable dashboard functionality
- `README.md` - This documentation
## Disclaimer
This code is provided for educational purposes only. The vulnerabilities demonstrated here are intentional and should never be implemented in production applications. Always follow security best practices when developing real applications.
## Learning Resources
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [Web Security Academy](https://portswigger.net/web-security)
- [Mozilla Developer Network Security](https://developer.mozilla.org/en-US/docs/Web/Security)

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard - Vulnerable Demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="warning-banner">
⚠️ EDUCATIONAL DEMO - INTENTIONALLY VULNERABLE ⚠️
</div>
<div class="dashboard">
<header class="dashboard-header">
<h1>Admin Dashboard</h1>
<div class="user-info">
<span>Welcome, <span id="currentUser">Unknown</span></span>
<button onclick="logout()">Logout</button>
</div>
</header>
<div class="dashboard-content">
<div class="stats-grid">
<div class="stat-card">
<h3>Users</h3>
<p class="stat-number">1,234</p>
</div>
<div class="stat-card">
<h3>Active Sessions</h3>
<p class="stat-number">56</p>
</div>
<div class="stat-card">
<h3>Security Alerts</h3>
<p class="stat-number">⚠️ MANY</p>
</div>
</div>
<div class="admin-panel">
<h3>Admin Actions</h3>
<div class="action-section">
<h4>Execute Command (XSS Vulnerable):</h4>
<input type="text" id="commandInput" placeholder="Enter command...">
<button onclick="executeCommand()">Execute</button>
<div id="commandOutput"></div>
</div>
<div class="action-section">
<h4>User Search (SQL Injection Vulnerable Simulation):</h4>
<input type="text" id="searchInput" placeholder="Search users...">
<button onclick="searchUsers()">Search</button>
<div id="searchResults"></div>
</div>
<div class="action-section">
<h4>System Information:</h4>
<div id="systemInfo">
<p>Server: vulnerable-demo.local</p>
<p>Database: mysql://admin:password123@localhost/users</p>
<p>Session ID: <span id="sessionId"></span></p>
<p>Stored Credentials: <span id="storedCreds"></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="dashboard.js"></script>
</body>
</html>

198
security-demo/dashboard.js Normal file
View file

@ -0,0 +1,198 @@
// VULNERABLE DASHBOARD SCRIPT - FOR EDUCATIONAL PURPOSES ONLY
// This script contains intentional security vulnerabilities
// Check if user is "authenticated" (vulnerability: client-side check only)
window.addEventListener('DOMContentLoaded', function() {
const urlParams = new URLSearchParams(window.location.search);
const userCredentials = JSON.parse(localStorage.getItem('userCredentials') || '{}');
// Vulnerability 1: Authentication data in URL parameters
const urlUser = urlParams.get('user');
const urlPass = urlParams.get('pass');
if (!userCredentials.username && !urlUser) {
alert('Access denied! Redirecting to login...');
window.location.href = 'index.html';
return;
}
// Vulnerability 2: Display sensitive information
const currentUser = userCredentials.username || urlUser || 'Unknown';
document.getElementById('currentUser').textContent = currentUser;
// Vulnerability 3: Expose session information
const sessionId = userCredentials.sessionId || urlParams.get('session') || 'no-session';
document.getElementById('sessionId').textContent = sessionId;
// Vulnerability 4: Display stored credentials in plain text
document.getElementById('storedCreds').innerHTML =
`Username: ${userCredentials.username || 'N/A'},
Password: ${userCredentials.password || 'N/A'}`;
// Vulnerability 5: Log sensitive data to console
console.log('User logged in:', {
username: currentUser,
credentials: userCredentials,
urlParams: Object.fromEntries(urlParams)
});
});
// Vulnerability 6: XSS in command execution
function executeCommand() {
const command = document.getElementById('commandInput').value;
const output = document.getElementById('commandOutput');
// NEVER use innerHTML with user input!
output.innerHTML = `<strong>Executing:</strong> ${command}<br>`;
// Simulate command execution with XSS vulnerability
if (command.toLowerCase().includes('alert')) {
// This allows XSS attacks
output.innerHTML += `<div style="color: green;">
Command result: ${command}
<script>${command}</script>
</div>`;
} else if (command.toLowerCase().includes('script')) {
// Another XSS vector
output.innerHTML += `<div>${command}</div>`;
} else {
output.innerHTML += `<div style="color: blue;">
Command "${command}" executed successfully!<br>
Output: System response for ${command}
</div>`;
}
// Vulnerability 7: Eval injection
if (command.startsWith('eval:')) {
try {
const code = command.substring(5);
eval(code); // NEVER do this!
output.innerHTML += `<div style="color: red;">⚠️ Eval executed: ${code}</div>`;
} catch (e) {
output.innerHTML += `<div style="color: red;">Eval error: ${e.message}</div>`;
}
}
}
// Vulnerability 8: SQL Injection simulation
function searchUsers() {
const searchTerm = document.getElementById('searchInput').value;
const results = document.getElementById('searchResults');
// Simulate SQL injection vulnerability
let query = `SELECT * FROM users WHERE username LIKE '%${searchTerm}%'`;
results.innerHTML = `<strong>SQL Query:</strong><br><code>${query}</code><br><br>`;
// Show how SQL injection might work
if (searchTerm.includes("'") || searchTerm.includes(';') || searchTerm.includes('--')) {
results.innerHTML += `<div style="color: red; background: #ffebee; padding: 10px;">
<strong>SQL INJECTION DETECTED!</strong><br>
Malicious query detected: <code>${searchTerm}</code><br>
In a real application, this could expose the entire database!<br><br>
<strong>Simulated exposed data:</strong><br>
admin:password123<br>
user1:123456<br>
user2:qwerty<br>
All credit card numbers<br>
All personal information
</div>`;
} else {
// Normal search simulation
const fakeResults = [
'admin (Administrator)',
'testuser (Test User)',
'guest (Guest User)'
].filter(user => user.toLowerCase().includes(searchTerm.toLowerCase()));
if (fakeResults.length > 0) {
results.innerHTML += '<strong>Results:</strong><br>' +
fakeResults.map(user => `${user}`).join('<br>');
} else {
results.innerHTML += '<em>No users found.</em>';
}
}
}
// Vulnerability 9: Insecure logout
function logout() {
// Vulnerability: Not properly clearing sensitive data
localStorage.removeItem('userCredentials');
// Vulnerability: Sensitive data still in memory/console
console.log('User logged out, but session data may still be accessible');
// Vulnerability: No server-side session invalidation
alert('Logged out! (Note: In a real app, server-side session should be invalidated)');
window.location.href = 'index.html';
}
// Vulnerability 10: Expose admin functions globally
window.adminFunctions = {
deleteAllUsers: function() {
console.log('🔓 VULNERABILITY: Admin function exposed!');
alert('All users deleted! (Simulated)');
},
resetPasswords: function() {
console.log('🔓 VULNERABILITY: Password reset function exposed!');
alert('All passwords reset to "123456"! (Simulated)');
},
exportData: function() {
console.log('🔓 VULNERABILITY: Data export function exposed!');
const sensitiveData = {
users: ['admin', 'user1', 'user2'],
passwords: ['password123', '123456', 'qwerty'],
creditCards: ['4111-1111-1111-1111', '4222-2222-2222-2222'],
ssn: ['123-45-6789', '987-65-4321']
};
console.log('Exported sensitive data:', sensitiveData);
alert('Sensitive data exported to console!');
}
};
// Vulnerability 11: Automatic data exposure
setInterval(function() {
// Continuously expose sensitive information
window.currentSessionData = {
user: document.getElementById('currentUser').textContent,
sessionId: document.getElementById('sessionId').textContent,
loginTime: new Date().toISOString(),
permissions: ['read', 'write', 'admin', 'delete'],
apiKeys: {
database: 'db_key_12345',
payment: 'pay_key_67890',
admin: 'admin_key_abcde'
}
};
}, 1000);
// Vulnerability 12: Debug panel
if (window.location.search.includes('debug=true')) {
document.body.insertAdjacentHTML('beforeend', `
<div style="position: fixed; bottom: 10px; right: 10px; background: red; color: white; padding: 10px; border-radius: 5px; z-index: 1000;">
<strong>🔓 DEBUG MODE</strong><br>
<button onclick="window.adminFunctions.deleteAllUsers()">Delete Users</button><br>
<button onclick="window.adminFunctions.resetPasswords()">Reset Passwords</button><br>
<button onclick="window.adminFunctions.exportData()">Export Data</button><br>
<button onclick="console.log(window.currentSessionData)">Show Session</button>
</div>
`);
}
// Vulnerability 13: CSRF vulnerability
window.performAdminAction = function(action) {
// No CSRF protection
console.log(`Performing admin action: ${action}`);
alert(`Admin action "${action}" executed! (No CSRF protection)`);
};
// Auto-expose vulnerabilities in console
console.log('🔓 Available vulnerability demonstrations:');
console.log('• Try: executeCommand() with XSS payload like <script>alert("XSS")</script>');
console.log('• Try: searchUsers() with SQL injection like \' OR 1=1 --');
console.log('• Try: window.adminFunctions.deleteAllUsers()');
console.log('• Try: Add ?debug=true to URL for debug panel');
console.log('• Check: window.currentSessionData for exposed session info');

54
security-demo/index.html Normal file
View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vulnerable Login Demo - Educational Purpose</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="warning-banner">
⚠️ EDUCATIONAL DEMO - INTENTIONALLY VULNERABLE ⚠️
<p>This website contains deliberate security vulnerabilities for educational purposes only.</p>
</div>
<div class="login-form">
<h2>Admin Login</h2>
<form id="loginForm">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">Login</button>
</form>
<div id="loginMessage"></div>
<div class="demo-credentials">
<h3>Demo Credentials:</h3>
<p>Username: admin</p>
<p>Password: password123</p>
<p><em>Try different combinations to see vulnerabilities in action!</em></p>
</div>
</div>
<div class="vulnerability-info">
<h3>Security Vulnerabilities Demonstrated:</h3>
<ul>
<li>Plain text password storage in localStorage</li>
<li>No protection against brute force attacks</li>
<li>XSS vulnerability through innerHTML</li>
<li>Insecure credential transmission</li>
<li>Client-side authentication logic</li>
</ul>
</div>
</div>
<script src="login.js"></script>
</body>
</html>

119
security-demo/login.js Normal file
View file

@ -0,0 +1,119 @@
// VULNERABLE LOGIN SCRIPT - FOR EDUCATIONAL PURPOSES ONLY
// This script contains intentional security vulnerabilities
// Vulnerability 1: Plain text password storage
const STORED_CREDENTIALS = {
username: 'admin',
password: 'password123' // NEVER store passwords in plain text!
};
// Vulnerability 2: Expose credentials in global scope
window.adminCredentials = STORED_CREDENTIALS;
// Vulnerability 3: No rate limiting - allows brute force attacks
let loginAttempts = 0;
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const messageDiv = document.getElementById('loginMessage');
loginAttempts++;
// Vulnerability 4: Expose attempt count in console (information disclosure)
console.log(`Login attempt #${loginAttempts} for user: ${username}`);
console.log('Stored credentials:', STORED_CREDENTIALS);
// Vulnerability 5: Client-side authentication (easily bypassed)
if (username === STORED_CREDENTIALS.username && password === STORED_CREDENTIALS.password) {
// Vulnerability 6: Store credentials in localStorage (insecure)
localStorage.setItem('userCredentials', JSON.stringify({
username: username,
password: password, // NEVER store passwords!
loginTime: new Date().toISOString(),
sessionId: Math.random().toString(36).substr(2, 9)
}));
// Vulnerability 7: Store session in URL parameters
window.location.href = `dashboard.html?user=${username}&pass=${password}&session=${Math.random().toString(36)}`;
} else {
// Vulnerability 8: Information disclosure - revealing valid usernames
if (username === STORED_CREDENTIALS.username) {
messageDiv.innerHTML = `<div style="color: red; background: #ffebee; padding: 10px; border-radius: 4px;">
Incorrect password for user "${username}". Try again!
</div>`;
} else {
messageDiv.innerHTML = `<div style="color: red; background: #ffebee; padding: 10px; border-radius: 4px;">
User "${username}" not found. Valid username is "admin".
</div>`;
}
// Vulnerability 9: XSS vulnerability - using innerHTML with user input
setTimeout(() => {
messageDiv.innerHTML = `<div style="color: red;">
Failed login attempt for: ${username}<br>
<script>console.log('XSS executed!')</script>
Attempts: ${loginAttempts}
</div>`;
}, 1000);
}
});
// Vulnerability 10: Expose sensitive functions globally
window.bypassLogin = function() {
console.log('🔓 VULNERABILITY: Login bypass function exposed!');
localStorage.setItem('userCredentials', JSON.stringify({
username: 'admin',
password: 'password123',
loginTime: new Date().toISOString(),
sessionId: 'bypassed-session'
}));
window.location.href = 'dashboard.html?bypassed=true';
};
// Vulnerability 11: Debug mode exposure
window.DEBUG_MODE = true;
if (window.DEBUG_MODE) {
console.log('🔓 DEBUG MODE ENABLED - Security features disabled!');
console.log('🔓 Use window.bypassLogin() to bypass authentication!');
console.log('🔓 Stored credentials:', STORED_CREDENTIALS);
}
// Vulnerability 12: Eval injection vulnerability
window.executeUserCode = function(code) {
try {
// NEVER use eval() with user input!
eval(code);
} catch (e) {
console.error('Code execution error:', e);
}
};
// Vulnerability 13: Expose localStorage contents
setInterval(() => {
if (window.DEBUG_MODE) {
console.log('Current localStorage:', localStorage);
}
}, 5000);
// Vulnerability 14: CSRF token simulation (but it's predictable)
window.csrfToken = 'csrf_' + Date.now(); // Predictable token
console.log('CSRF Token:', window.csrfToken);
// Add some visual feedback for demo purposes
document.addEventListener('DOMContentLoaded', function() {
const usernameField = document.getElementById('username');
const passwordField = document.getElementById('password');
// Show credential hints on focus (bad practice)
usernameField.addEventListener('focus', function() {
console.log('Hint: Try "admin"');
});
passwordField.addEventListener('focus', function() {
console.log('Hint: Try "password123"');
});
});

286
security-demo/styles.css Normal file
View file

@ -0,0 +1,286 @@
/* CSS Styles for Vulnerable Demo */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
width: 100%;
max-width: 800px;
margin: 20px;
}
.warning-banner {
background: #ff4444;
color: white;
padding: 15px;
text-align: center;
border-radius: 8px;
margin-bottom: 20px;
font-weight: bold;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.warning-banner p {
margin-top: 5px;
font-size: 14px;
font-weight: normal;
}
.login-form {
background: white;
padding: 40px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
margin-bottom: 20px;
}
.login-form h2 {
text-align: center;
margin-bottom: 30px;
color: #333;
font-size: 28px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: #555;
font-weight: bold;
}
.form-group input {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: border-color 0.3s;
}
.form-group input:focus {
outline: none;
border-color: #667eea;
}
button {
width: 100%;
padding: 12px;
background: #667eea;
color: white;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: #5a6fd8;
}
#loginMessage {
margin-top: 15px;
padding: 10px;
border-radius: 4px;
text-align: center;
}
.demo-credentials {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin-top: 20px;
text-align: center;
}
.demo-credentials h3 {
color: #333;
margin-bottom: 10px;
}
.vulnerability-info {
background: white;
padding: 30px;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.vulnerability-info h3 {
color: #d73527;
margin-bottom: 15px;
}
.vulnerability-info ul {
list-style-type: none;
padding-left: 0;
}
.vulnerability-info li {
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.vulnerability-info li:before {
content: "🔓 ";
margin-right: 8px;
}
/* Dashboard Styles */
.dashboard {
background: white;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.dashboard-header {
background: #667eea;
color: white;
padding: 20px 30px;
display: flex;
justify-content: space-between;
align-items: center;
}
.dashboard-header h1 {
font-size: 24px;
}
.user-info {
display: flex;
align-items: center;
gap: 15px;
}
.user-info button {
width: auto;
padding: 8px 16px;
background: #ff4444;
font-size: 14px;
}
.dashboard-content {
padding: 30px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
text-align: center;
border: 1px solid #e9ecef;
}
.stat-card h3 {
color: #495057;
margin-bottom: 10px;
}
.stat-number {
font-size: 24px;
font-weight: bold;
color: #667eea;
}
.admin-panel {
border-top: 2px solid #e9ecef;
padding-top: 30px;
}
.admin-panel h3 {
color: #333;
margin-bottom: 20px;
}
.action-section {
background: #f8f9fa;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
.action-section h4 {
color: #495057;
margin-bottom: 15px;
}
.action-section input {
width: calc(100% - 120px);
margin-right: 10px;
margin-bottom: 10px;
}
.action-section button {
width: 100px;
padding: 12px;
}
#commandOutput, #searchResults {
margin-top: 15px;
padding: 15px;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
min-height: 50px;
}
#systemInfo {
background: #fff;
padding: 15px;
border-radius: 4px;
border: 1px solid #ddd;
}
#systemInfo p {
margin-bottom: 8px;
font-family: monospace;
}
/* Mobile Responsiveness */
@media (max-width: 768px) {
.container {
margin: 10px;
}
.login-form, .dashboard-content {
padding: 20px;
}
.dashboard-header {
flex-direction: column;
gap: 15px;
text-align: center;
}
.action-section input {
width: 100%;
margin-right: 0;
margin-bottom: 10px;
}
.action-section button {
width: 100%;
}
}