pythonCopy code@app.route('/profile/<user_id>')
def profile(user_id):
user = db.get_user(user_id)
return render_template('profile.html', user=user)
Reason for vulnerability: Directly accessing user data by user_id without verifying that the current user has permission to view that data.
Fixed Code:
pythonCopy code@app.route('/profile/<user_id>')
@login_required
def profile(user_id):
if user_id != current_user.id:
abort(403)
user = db.get_user(user_id)
return render_template('profile.html', user=user)
Reason for fix: Adding access control checks ensures that users can only access their own data, preventing unauthorized access.
Vulnerable Code:
javaCopy codeString userId = request.getParameter("userId");
User user = userService.getUserById(userId);
Reason for vulnerability: No access control check, allowing any user to access any user data.
Fixed Code:
javaCopy codeString userId = request.getParameter("userId");
if (!currentUser.getId().equals(userId)) {
throw new UnauthorizedException();
}
User user = userService.getUserById(userId);
Reason for fix: Check if the current user is authorized to access the requested user data.
$user_id = $_GET['user_id'];
$user_data = $db->query("SELECT * FROM users WHERE id = '$user_id'");
Reason for vulnerability: The code uses user-input to directly access a database record without proper authorization. Fixed Code 1 (PHP):
$user_id = $_GET['user_id'];
if (isset($_SESSION['user_id']) && $_SESSION['user_id'] == $user_id) {
$user_data = $db->query("SELECT * FROM users WHERE id = '$user_id'");
} else {
// handle unauthorized access
}
Reason for fix: The code checks if the user is authenticated and authorized to access the requested user data. Vulnerable Code 2 (Java):
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String userId = request.getParameter("userId");
User user = userDao.getUser(userId);
// ...
}
Reason for vulnerability: The code uses user-input to directly access a user object without proper authorization. Fixed Code 2 (Java):
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String userId = request.getParameter("userId");
if (request.isUserInRole("admin") || userId.equals(request.getRemoteUser())) {
User user = userDao.getUser(userId);
// ...
} else {
// handle unauthorized access
}
}
Reason for fix: The code checks if the user is authenticated and authorized to access the requested user data.
Vulnerable Code
@RestController
public class UserController {
@GetMapping("/api/users/{userId}/profile")
public ResponseEntity<UserProfile> getUserProfile(@PathVariable Long userId) {
UserProfile profile = userService.getUserProfile(userId);
return ResponseEntity.ok(profile);
}
}
Reason for Vulnerability:
This endpoint doesn't check if the requesting user has permission to access the profile for the given userId, allowing any authenticated user to access any profile.
Fixed Code:
javaCopy@RestController
public class UserController {
@GetMapping("/api/users/{userId}/profile")
public ResponseEntity<UserProfile> getUserProfile(@PathVariable Long userId, Authentication authentication) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
if (!userService.canAccessProfile(userDetails.getUsername(), userId)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
UserProfile profile = userService.getUserProfile(userId);
return ResponseEntity.ok(profile);
}
}
Reason for Fix:
The fixed code checks if the authenticated user has permission to access the requested profile before returning it, preventing unauthorized access.
Java Example
Vulnerable Code:
javaCopy@WebServlet("/downloadFile")
public class FileDownloadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("file");
File file = new File("/path/to/files/" + fileName);
// Code to send file as response
}
}
Reason for Vulnerability:
This servlet allows downloading any file by specifying its name, potentially exposing sensitive files.
Fixed Code:
javaCopy@WebServlet("/downloadFile")
public class FileDownloadServlet extends HttpServlet {
private static final String FILE_PATH = "/path/to/files/";
private static final Set<String> ALLOWED_FILES = Set.of("public1.pdf", "public2.pdf");
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("file");
if (!ALLOWED_FILES.contains(fileName)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
File file = new File(FILE_PATH + fileName);
if (!file.getCanonicalPath().startsWith(FILE_PATH)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
// Code to send file as response
}
}
Reason for Fix:
The fixed code checks if the requested file is in the allowed list and uses canonical path checking to prevent path traversal, ensuring only authorized files can be downloaded.
Python Example
Vulnerable Code:
pythonCopyfrom flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/api/notes/<int:note_id>', methods=['GET'])
def get_note(note_id):
with open('notes.json', 'r') as f:
notes = json.load(f)
if str(note_id) in notes:
return jsonify(notes[str(note_id)])
return jsonify({'error': 'Note not found'}), 404
if __name__ == '__main__':
app.run(debug=True)
Reason for Vulnerability:
This endpoint allows any user to access any note by its ID without checking ownership or permissions.
Fixed Code:
pythonCopyfrom flask import Flask, request, jsonify
import json
from functools import wraps
app = Flask(__name__)
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not request.headers.get('Authorization'):
return jsonify({'error': 'No authorization token provided'}), 401
# Implement proper token verification here
return f(*args, **kwargs)
return decorated_function
@app.route('/api/notes/<int:note_id>', methods=['GET'])
@login_required
def get_note(note_id):
user_id = get_user_id_from_token(request.headers.get('Authorization'))
with open('notes.json', 'r') as f:
notes = json.load(f)
if str(note_id) in notes and notes[str(note_id)]['owner_id'] == user_id:
return jsonify(notes[str(note_id)])
return jsonify({'error': 'Note not found or access denied'}), 404
def get_user_id_from_token(token):
# Implement token verification and return user_id
pass
if __name__ == '__main__':
app.run(debug=True)
Reason for Fix:
The fixed code adds authentication and checks if the requesting user is the owner of the note before returning it, preventing unauthorized access.