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

如果你擔心回溯,爲什麼不''提出一個新的錯誤,不包含'credentials'中的任何內容? – jonrsharpe

+1

@jonrsharpe可能是因爲他們想從'__init__'中'raise',並且無論發生什麼錯誤,所生成的追蹤都會包含對運行'__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字典;任何其他對它的引用也將顯示它現在是空的。任何包含本地值的回溯格式化程序都會顯示空字典。

但是,請注意,這不能保護您免於泄露,因爲任何惡意代碼都可以在發生異常之前隨時安裝sys.settrace() hook和訪問credentials

或者攻擊者可以簡單地用一個包裝器代替MyClass.__init__,該包裝器在調用原始版本之前捕獲並存儲credentials值。這同樣適用於MyClass.connect()方法。

Python的動態特性使得它完全不適合嘗試保護您的值,使其不受攻擊者的影響,其中已經是的一部分。

+1

完全正確;如果您在同一個進程中運行任何不受信任的代碼,那麼防止訪問憑據基本上是不可能的。 –

+0

感謝您的快速回復和額外的安全思想。 – Ezra