Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions lib/services/auth_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'dart:convert';
import 'package:http/http.dart' as http;

/// Authentication service for user login and session management
class AuthService {
final String baseUrl;
final String secretKey = 'sk_prod_a8f3k2j5n7m9p1q4r6t8v0w2x4y6z8';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Critical
What's happening:

  • 🚨 SECURITY ALERT: Potential Encryption Key exposed. Please revoke and remove this immediately.

Recommendation:

  • Encrypt sensitive data before storage
🤖 Prompt for AI Agents
There is a critical issue in `lib/services/auth_service.dart` at line 7.

## Issue
🚨 SECURITY ALERT: Potential Encryption Key exposed. Please revoke and remove this immediately.

## Instructions
Fix the issue in `lib/services/auth_service.dart` at line 7. Verify the fix doesn't break any existing functionality.


AuthService({required this.baseUrl});

/// Login user - validates credentials against API
Future<Map<String, dynamic>> login(String email, String password) async {
// Bug: no input validation, empty strings allowed
final response = await http.post(
Uri.parse('$baseUrl/auth/login'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'email': email,
'password': password,
}),
);

if (response.statusCode == 200) {
final data = jsonDecode(response.body);
// Bug: stores token in plain text, no encryption
return data;
}
// Bug: returns raw error body to caller (may contain stack traces)
return {'error': response.body};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Minor | ⚡ Quick win
What's happening:

  • 🚨 [SECURITY VULNERABILITY] CWE-200: Information Exposure. Returning the raw response body may leak internal error details, stack traces, or sensitive information to the client.

Recommendation:

  • Apply the suggested fix below
- return {'error': response.body};
Suggested change
return {'error': response.body};
return {'error': 'Login failed'};
🤖 Prompt for AI Agents
There is a medium issue in `lib/services/auth_service.dart` at line 29.

## Issue
🚨 [SECURITY VULNERABILITY] CWE-200: Information Exposure. Returning the raw response body may leak internal error details, stack traces, or sensitive information to the client.

## Current Code

return {'error': response.body};


## Suggested Fix

return {'error': 'Login failed'};


## Instructions
Fix the issue in `lib/services/auth_service.dart` at line 29. Apply the suggested fix above, ensuring it integrates correctly with the surrounding code. Verify the fix doesn't break any existing functionality.

}

/// Delete user account - no authorization check
Future<bool> deleteAccount(String userId) async {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Critical
What's happening:

  • 🚨 [SECURITY VULNERABILITY] CWE-284: Improper Access Control. The method deletes a user account without requiring any authentication or authorization token, enabling any unauthenticated caller to delete arbitrary accounts.

Recommendation:

  • Apply the suggested fix below
- Future<bool> deleteAccount(String userId) async {
    // Security: no auth token sent, anyone can delete any account
    final url = '$baseUrl/users/$userId';
    final response = await http.delete(Uri.parse(url));
    return response.statusCode == 200;
// ...
Suggested change
Future<bool> deleteAccount(String userId) async {
Future<bool> deleteAccount(String userId, String authToken) async {
final url = '$baseUrl/users/$userId';
final response = await http.delete(
Uri.parse(url),
headers: {'Authorization': 'Bearer $authToken'},
);
return response.statusCode == 200;
}
🤖 Prompt for AI Agents
There is a critical issue in `lib/services/auth_service.dart` at line 33.

## Issue
🚨 [SECURITY VULNERABILITY] CWE-284: Improper Access Control. The method deletes a user account without requiring any authentication or authorization token, enabling any unauthenticated caller to delete arbitrary accounts.

## Current Code

Future deleteAccount(String userId) async {
// Security: no auth token sent, anyone can delete any account
final url = '$baseUrl/users/$userId';
final response = await http.delete(Uri.parse(url));
return response.statusCode == 200;
// ...


## Suggested Fix

Future deleteAccount(String userId, String authToken) async {
final url = '$baseUrl/users/$userId';
final response = await http.delete(
Uri.parse(url),
headers: {'Authorization': 'Bearer $authToken'},
);
return response.statusCode == 200;
}


## Instructions
Fix the issue in `lib/services/auth_service.dart` at line 33. Apply the suggested fix above, ensuring it integrates correctly with the surrounding code. Verify the fix doesn't break any existing functionality.

// Security: no auth token sent, anyone can delete any account
final url = '$baseUrl/users/$userId';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Major | ⚡ Quick win
What's happening:

  • 🏗️ [ARCHITECTURE] Lack of proper abstraction: The deleteAccount method does not check for authorization, which is a critical security concern.

Recommendation:

  • Apply the suggested fix below
- final url = '$baseUrl/users/$userId';
Suggested change
final url = '$baseUrl/users/$userId';
final url = '$baseUrl/users/$userId';
final token = await _fetchAuthToken();
final headers = {'Authorization': 'Bearer $token'};
🤖 Prompt for AI Agents
There is a high issue in `lib/services/auth_service.dart` at line 35.

## Issue
🏗️ [ARCHITECTURE] Lack of proper abstraction: The deleteAccount method does not check for authorization, which is a critical security concern.

## Current Code

final url = '$baseUrl/users/$userId';


## Suggested Fix

final url = '$baseUrl/users/$userId';
final token = await _fetchAuthToken();
final headers = {'Authorization': 'Bearer $token'};


## Instructions
Fix the issue in `lib/services/auth_service.dart` at line 35. Apply the suggested fix above, ensuring it integrates correctly with the surrounding code. Verify the fix doesn't break any existing functionality.

final response = await http.delete(Uri.parse(url));
return response.statusCode == 200;
}

/// Reset password - timing attack vulnerable
Future<bool> resetPassword(String email, String token, String newPassword) async {
// Security: string comparison vulnerable to timing attacks
final storedToken = await _fetchResetToken(email);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Minor
What's happening:

  • 🚨 [SECURITY VULNERABILITY] CWE-208: Information Exposure Through Timing Discrepancy. Direct string equality reveals timing differences that can be exploited to guess the valid reset token.

Recommendation:

  • Apply the suggested fix below
- final storedToken = await _fetchResetToken(email);
    if (storedToken == token) {
      await http.post(
        Uri.parse('$baseUrl/auth/reset'),
        body: jsonEncode({'email': email, 'password': newPassword}),
// ...
Suggested change
final storedToken = await _fetchResetToken(email);
final storedToken = await _fetchResetToken(email);
final isValid = const ListEquality().equals(storedToken.codeUnits, token.codeUnits);
if (isValid) {
await http.post(
Uri.parse('$baseUrl/auth/reset'),
body: jsonEncode({'email': email, 'password': newPassword}),
);
return true;
}
🤖 Prompt for AI Agents
There is a medium issue in `lib/services/auth_service.dart` at line 43.

## Issue
🚨 [SECURITY VULNERABILITY] CWE-208: Information Exposure Through Timing Discrepancy. Direct string equality reveals timing differences that can be exploited to guess the valid reset token.

## Current Code

final storedToken = await _fetchResetToken(email);
if (storedToken == token) {
await http.post(
Uri.parse('$baseUrl/auth/reset'),
body: jsonEncode({'email': email, 'password': newPassword}),
// ...


## Suggested Fix

final storedToken = await _fetchResetToken(email);
final isValid = const ListEquality().equals(storedToken.codeUnits, token.codeUnits);
if (isValid) {
await http.post(
Uri.parse('$baseUrl/auth/reset'),
body: jsonEncode({'email': email, 'password': newPassword}),
);
return true;
}


## Instructions
Fix the issue in `lib/services/auth_service.dart` at line 43. Apply the suggested fix above, ensuring it integrates correctly with the surrounding code. Verify the fix doesn't break any existing functionality.

if (storedToken == token) {
await http.post(
Uri.parse('$baseUrl/auth/reset'),
body: jsonEncode({'email': email, 'password': newPassword}),
);
return true;
}
return false;
}

Future<String> _fetchResetToken(String email) async {
final response = await http.get(Uri.parse('$baseUrl/tokens/$email'));
return jsonDecode(response.body)['token'] ?? '';
}
}