1

Я пытаюсь найти хороший способ обработки ошибок в __init__(), не обнаруживая конфиденциальных данных в трассировке.Python (2.7): Обработка ошибок в __init__ с чувствительной информацией

У меня есть класс на основе pxssh, и я выполняю мое соединение в __init__(). Целью является инициализация объекта для отправки команд CLI дочернему устройству.

class MyClass(pxssh.pxssh): 
    def __init__(self, credentials): 
    . 
    . 
    . 
    try: 
     self.connect(credentials) 
    except Exception as e: 
     stderr.write('Error: %s\n' % str(e) 
     exit(1) 

Это был хорош для тестирования, но этот класс предназначен для использования другого кода, и я не хочу идти убивать вызывающий с exit(1).

Я бы использовал raise вместо exit(1), но проблема в том, что credentials - это словарь, содержащий пароль и другую конфиденциальную информацию о соединении. Я не хочу, чтобы он сбрасывался в трассировку, если вызывающий абонент просто поднимает все исключения, которые я бросаю.

Какой был бы лучший способ справиться с этой ситуацией?

Спасибо!

+0

Если вы беспокоитесь о трассировке, почему бы не «поднять» новую ошибку, которая не содержит ничего из «учетных данных»? – jonrsharpe

+1

@jonrsharpe, вероятно, потому, что они хотят «поднять» из '__init__', и независимо от того, какая ошибка возникла, созданная таким образом трассировка будет включать ссылку на фрейм, в котором запущен' __init__' (включая словарь 'credentials') –

+0

@ Да, я вижу. Хорошо, если OP обеспокоен атаками в процессе, как вы прокомментируете ниже, сделать нечего! – jonrsharpe

ответ

2

Вы можете поймать исключение, очистить секретную информацию, а затем ререйз:

class MyClass(pxssh.pxssh): 
    def __init__(self, credentials): 
     # ... 
     try: 
      self.connect(credentials) 
     except Exception as e: 
      credentials.clear() 
      raise 

Это опустошает credentials словаря в целом; любые другие ссылки на него также покажут, что теперь он пуст. Любой форматор трассировки, который включает значения locals, вместо этого отображает пустой словарь.

Однако обратите внимание, что это не может защитить вас от раскрытия информации, так как любой вредоносный код может просто установить sys.settrace() hook и получить доступ к credentials в любое время, когда он существует до возникновения исключения.

Или злоумышленник может просто заменить MyClass.__init__ на обертку, которая захватывает и сохраняет значение credentials перед вызовом исходной версии. То же самое относится к методу MyClass.connect().

Динамическая природа Python делает его совершенно непригодным для защиты ваших ценностей от злоумышленника, который уже уже часть вашего процесса.

+1

Совершенно верно; если у вас есть ненадежный код, запущенный в том же процессе, практически невозможно защитить его от доступа к учетным данным. –

+0

Спасибо за быстрый ответ и лишние мысли о безопасности. – Ezra