В первой части мы разобрали, почему IDOR — это не «забыли проверку», а системная ошибка доверия клиенту. Теперь — как эта ошибка выглядит в реальном коде:
@app.route('/api/orders/<order_id>')
def get_order(order_id):
order = db.query(f"SELECT * FROM orders WHERE id={order_id}")
return jsonify(order)
# Любой может запросить GET /api/orders/12345
// Frontend
fetch(`/api/profile/${userId}`)
// userId взят из URL или localStorage — легко подменить
Проблема в том, что сервер:
— доверяет идентификатору от клиента
— не проверяет владение ресурсом
— считает факт доступа достаточным основанием для ответа
✅ Как правильно закрывать IDOR:
@app.route('/api/orders/<order_id>')
@login_required
def get_order(order_id):
order = Order.query.get_or_404(order_id)
if order.user_id != current_user.id:
abort(403)
return jsonify(order)
SELECT * FROM orders
WHERE id = ? AND user_id = ?
Ключевой принцип: каждый запрос к объекту = отдельная проверка прав.
Почему такие баги проходят мимо:
— функционал корректен для «нормального» пользователя
— тесты не проверяют доступ к чужим объектам
— бизнес-логика не формализована
— ревью смотрит на код, а не на модель доступа
📍 Навигация: [Вакансии]
🐸 Библиотека хакера
#breach_breakdown
