![](/img/trans.png)
[英]How can I tell if my PHP S3 class putObjectFile() process has completed?
[英]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
釋放內存? 我怎樣才能斷言它已被安全發布以將其應用於我將來可能會對其他擴展程序?
我不是安全分析師,所以我對安全的定義相當含糊。
在我看之前,我的答案是:由於PHP是一種動態語言,你應該假設它在被證明不是之前就不會被清除 (例如使用Volatility)。 根據前FreeBSD安全官Colin Percival的說法, “歸零緩沖區不足” - 所以它甚至可能都不重要。
但這是一個令人難以置信的無聊答案。 引擎蓋下有什么?
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()
的指針。 在這些操作中,我沒有看到任何將內存清零的嘗試。
如果您可以安裝PECL擴展, libsodium除安全內存分配實用程序外還提供\\Sodium\\memzero()
。
請記住,歸零內存是一種緩解策略,用於何時發生折衷。 如果您的PHP代碼可以從磁盤(或從數據庫)讀取私鑰,攻擊者可能會重放代碼並直接竊取密鑰。 防止這種情況的方法是將密鑰存儲在硬件安全模塊中 ,不要直接觸摸它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.