簡體   English   中英

如何判斷我的內存是否已被PHP應用程序安全釋放?

[英]How can I tell if my memory has been released securely by a PHP application?

這可能更適合security.stackexchange.com,但我特別好奇PHP。

我在應用程序中使用openssl,我注意到openssl資源的免費操作。 這很可能只是一個通用的內存版本,但鑒於加密性質,它可以作為特殊情況處理。

應用程序空間內的AFAIK無法確保從內存中刪除變量。 但是,在Zend的土地上,C擴展是否會清除已知的敏感數據,還是只釋放內存? openssl_pkey_free是否openssl_pkey_free釋放內存? 我怎樣才能斷言它已被安全發布以將其應用於我將來可能會對其他擴展程序?

我不是安全分析師,所以我對安全的定義相當含糊。

TL; DR:不。

在我看之前,我的答案是:由於PHP是一種動態語言,你應該假設它在被證明不是之前就不會被清除 (例如使用Volatility)。 根據前FreeBSD安全官Colin Percival的說法, “歸零緩沖區不足” - 所以它甚至可能都不重要。

但這是一個令人難以置信的無聊答案。 引擎蓋下有什么?

openssl_pkey_free()有什么作用?

openssl_pkey_free()由PHP在ext / openssl / openssl.c#545中定義

void EVP_PKEY_free(EVP_PKEY *x)
{
    int i;

    if (x == NULL)
        return;

    i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
#ifdef REF_PRINT
    REF_PRINT("EVP_PKEY", x);
#endif
    if (i > 0)
        return;
#ifdef REF_CHECK
    if (i < 0) {
        fprintf(stderr, "EVP_PKEY_free, bad reference count\n");
        abort();
    }
#endif
    EVP_PKEY_free_it(x);
    if (x->attributes)
        sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
    OPENSSL_free(x);
}

static void EVP_PKEY_free_it(EVP_PKEY *x)
{
    if (x->ameth && x->ameth->pkey_free) {
        x->ameth->pkey_free(x);
        x->pkey.ptr = NULL;
    }
#ifndef OPENSSL_NO_ENGINE
    if (x->engine) {
        ENGINE_finish(x->engine);
        x->engine = NULL;
    }
#endif
}

如您所見,它調用一個名為EVP_PKEY_free()的函數,該函數由/crypto/evp/p_lib.c#L376中的openssl定義:

void EVP_PKEY_free(EVP_PKEY *x)
{
    int i;

    if (x == NULL)
        return;

    i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
#ifdef REF_PRINT
    REF_PRINT("EVP_PKEY", x);
#endif
    if (i > 0)
        return;
#ifdef REF_CHECK
    if (i < 0) {
        fprintf(stderr, "EVP_PKEY_free, bad reference count\n");
        abort();
    }
#endif
    EVP_PKEY_free_it(x);
    if (x->attributes)
        sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
    OPENSSL_free(x);
}

它會進行一些健全性檢查,然后調用OPENSSL_free() ,它只是CRYPTO_free() 的別名

最后, CRYPTO_free() 在這里定義:

void CRYPTO_free(void *str)
{
    if (free_debug_func != NULL)
        free_debug_func(str, 0);
#ifdef LEVITTE_DEBUG_MEM
    fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
#endif
    free_func(str);
    if (free_debug_func != NULL)
        free_debug_func(NULL, 1);
}

它似乎只是在典型的情況下調用free_func() ,它是一個指向free()的指針。 在這些操作中,我沒有看到任何將內存清零的嘗試。

但我真的想在PHP中將內存歸零。 我怎樣才能?!

如果您可以安裝PECL擴展, libsodium安全內存分配實用程序外還提供\\Sodium\\memzero()

請記住,歸零內存是一種緩解策略,用於何時發生折衷。 如果您的PHP代碼可以從磁盤(或從數據庫)讀取私鑰,攻擊者可能會重放代碼並直接竊取密鑰。 防止這種情況的方法是將密鑰存儲在硬件安全模塊中 ,不要直接觸摸它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM