Перейти к содержанию

Никогда не применять контроль доступа на стороне клиента

Описание

Контроль доступа на стороне клиента — это практика, при которой проверки прав доступа выполняются в коде, исполняемом на клиенте (например, в JavaScript). Это может привести к серьезным уязвимостям, так как злоумышленники могут легко обойти такие проверки, изменяя код или манипулируя запросами.

Почему это важно

  1. Безопасность данных: Если контроль доступа осуществляется на стороне клиента, злоумышленники могут получить доступ к данным или функциям, к которым у них нет прав, что может привести к утечке конфиденциальной информации.
  2. Устойчивость к манипуляциям: Проверки на стороне клиента могут быть изменены или удалены, что делает систему уязвимой для атак.
  3. Надежность системы: Полагание на клиентские проверки может привести к непредсказуемому поведению системы и снижению ее надежности.

Способы реализации с примерами

Проверка прав доступа на сервере: Все проверки прав доступа должны выполняться на сервере. Сервер должен проверять, имеет ли пользователь право на выполнение запрашиваемого действия.

Пример:

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');
    }
}

Проблема: В этом коде проверка прав доступа осуществляется на стороне клиента, что делает систему уязвимой для обхода.

Причины, к которым может привести несоблюдение требования

  1. Несанкционированный доступ: Злоумышленники могут обойти проверки на стороне клиента и получить доступ к защищенным ресурсам.
  2. Утечка данных: Если контроль доступа не реализован на сервере, это может привести к утечке конфиденциальной информации.
  3. Проблемы с безопасностью: Полагание на клиентские проверки увеличивает риск атак и снижает общую безопасность системы.

Рекомендации

  • Всегда выполняйте проверки прав доступа на сервере, а не на стороне клиента.
  • Удаляйте все проверки доступа из клиентского кода.
  • Используйте механизмы логирования и мониторинга для отслеживания попыток несанкционированного доступа.
  • Обучайте разработчиков важности контроля доступа на сервере и рисков, связанных с клиентскими проверками.