Никогда не применять контроль доступа на стороне клиента
Описание
Контроль доступа на стороне клиента — это практика, при которой проверки прав доступа выполняются в коде, исполняемом на клиенте (например, в JavaScript). Это может привести к серьезным уязвимостям, так как злоумышленники могут легко обойти такие проверки, изменяя код или манипулируя запросами.
Почему это важно
- Безопасность данных: Если контроль доступа осуществляется на стороне клиента, злоумышленники могут получить доступ к данным или функциям, к которым у них нет прав, что может привести к утечке конфиденциальной информации.
 - Устойчивость к манипуляциям: Проверки на стороне клиента могут быть изменены или удалены, что делает систему уязвимой для атак.
 - Надежность системы: Полагание на клиентские проверки может привести к непредсказуемому поведению системы и снижению ее надежности.
 
Способы реализации с примерами
Проверка прав доступа на сервере: Все проверки прав доступа должны выполняться на сервере. Сервер должен проверять, имеет ли пользователь право на выполнение запрашиваемого действия.
Пример:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api/resource', methods=['GET'])
def get_resource():
    user_id = request.args.get('user_id')
    resource_id = request.args.get('resource_id')
    if not has_access(user_id, resource_id):  # Проверка прав доступа на сервере
        return jsonify({'error': 'Access denied'}), 403
    return jsonify({'data': 'This is the resource data'})
Удаление клиентских проверок: Убедитесь, что в клиентском коде нет проверок прав доступа. Все проверки должны быть сосредоточены на сервере.
Пример:
// Уязвимый код на стороне клиента
if (userHasAccess) {
    fetch('/api/resource')
        .then(response => response.json())
        .then(data => console.log(data));
} else {
    console.log('Access denied');
}
Безопасный код:
// Удаление проверки на стороне клиента
fetch('/api/resource')
    .then(response => {
        if (!response.ok) {
            throw new Error('Access denied');
        }
        return response.json();
    })
    .then(data => console.log(data));
Логирование и мониторинг: Ведите логи всех запросов к защищенным ресурсам и проверяйте их на наличие подозрительной активности.
Пример:
import logging
logging.basicConfig(level=logging.INFO)
@app.route('/api/resource', methods=['GET'])
def get_resource():
    user_id = request.args.get('user_id')
    resource_id = request.args.get('resource_id')
    if not has_access(user_id, resource_id):
        logging.warning(f"Unauthorized access attempt by user {user_id} to resource {resource_id}")
        return jsonify({'error': 'Access denied'}), 403
    return jsonify({'data': 'This is the resource data'})
Примеры уязвимого кода
// Пример уязвимого кода на стороне клиента
function fetchResource() {
    if (userIsAdmin) {  // Проверка на стороне клиента
        fetch('/api/resource')
            .then(response => response.json())
            .then(data => console.log(data));
    } else {
        console.log('Access denied');
    }
}
Проблема: В этом коде проверка прав доступа осуществляется на стороне клиента, что делает систему уязвимой для обхода.
Причины, к которым может привести несоблюдение требования
- Несанкционированный доступ: Злоумышленники могут обойти проверки на стороне клиента и получить доступ к защищенным ресурсам.
 - Утечка данных: Если контроль доступа не реализован на сервере, это может привести к утечке конфиденциальной информации.
 - Проблемы с безопасностью: Полагание на клиентские проверки увеличивает риск атак и снижает общую безопасность системы.
 
Рекомендации
- Всегда выполняйте проверки прав доступа на сервере, а не на стороне клиента.
 - Удаляйте все проверки доступа из клиентского кода.
 - Используйте механизмы логирования и мониторинга для отслеживания попыток несанкционированного доступа.
 - Обучайте разработчиков важности контроля доступа на сервере и рисков, связанных с клиентскими проверками.