【发布时间】:2011-08-30 13:57:06
【问题描述】:
我实际上正在编写一个安全脚本,似乎我遇到了 PHP 和 PHP 使用内存方式的问题。
我的.php:
<?php
// Display current PID
echo 'pid= ', posix_getpid(), PHP_EOL;
// The user type a very secret key
echo 'Fill secret: ';
$my_secret_key = trim(fgets(STDIN));
// 'Destroty' the secret key
unset($my_secret_key);
// Wait for something
echo 'waiting...';
sleep(60);
现在我运行脚本:
php my.php
pid= 1402
Fill secret: AZERTY <= User input
waiting...
在脚本结束之前(睡眠时),我生成了一个向脚本发送 SIGSEV 信号的核心文件
kill -11 1402
我检查了核心文件:
strings core | less
这是结果的摘录:
...
fjssdd
sleep
STDIN
AZERTY <==== this is the secret key
zergdf
...
我知道内存只是在未设置的情况下被释放而不是“销毁”。数据并未真正删除(调用 free() 函数)
所以如果有人dump了进程的内存,即使在脚本执行之后,他也可以读取$my_secret_key(直到内存空间被另一个进程覆盖)
有没有办法在PHP脚本执行后覆盖整个内存空间的这个内存段?
感谢大家的cmets。
我现在已经知道系统是如何管理内存的了。
即使 PHP 不使用 malloc 和 free(但一些编辑版本,如 emalloc 或 efree),似乎(并且我理解为什么)PHP 在释放不允许的内存后根本不可能“垃圾”。
这个问题更多是出于好奇,每个 cmets 似乎都在确认我之前打算做的事情:用内存感知语言 (c?) 编写一小段代码,通过使用 malloc 分配一个简单的字符串来处理这个特殊部分, 使用 THEN freeing 后用 XXXXXX 覆盖。
谢谢大家
J
【问题讨论】:
-
您是否尝试过将
$my_secret_key设置为其他值,然后取消设置?例如$my_secret_key = null; unset($my_secret_key); -
这可能会奏效,但如果覆盖字符串的大小差异很大,这会变得不太确定。
-
赋值NULL实际上是取消设置,所以更好
$my_secret_key = '@@@@@@@@@@';也调用垃圾收集器之后取消设置:gc_collect_cycles();. -
@hakre 所以应该是
$my_secret_key = 'some string'; unset($my_secret_key); gc_collect_cycles();?很高兴知道以后! :) -
你的解决方案没有任何改变:(