読者です 読者をやめる 読者になる 読者になる

PHPコードをページからPOSTしてevalする

PHP

ありがちかもしれないけど、PHPコードをページからPOSTしてevalする対話的プログラムの窓口を書いてみた。CLIが封じられてる環境だと、エディタ→FTP→ブラウザ→ソースを見る→エディタ→FTP→ブラウザ→...がめんどくさいので。あと、管理で楽するために、「テストサイトのディレクトリに、このファイルを1個置くだけ」みたいにしたかった。

<?php
if(isset($_POST['code'])){
    header("Content-Type: text/plain; charset=utf-8");
    if(!isset($_POST['fullhtml'])){
        ob_start();
    }
    $old_de = ini_set('display_errors', 1);
    $old_er = error_reporting(E_ALL);
    eval($_POST['code']);
    error_reporting($old_er);
    ini_set('display_errors', $old_de);
    if(!isset($_POST['fullhtml'])){
       echo htmlspecialchars(ob_get_clean());
    }
    exit;
}
?>
<html><head><title>PHP code snippet tester via eval.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
function mouse_y(event){
    if(document.all){ return event.clientY; }else{ return event.pageY; }
}
function startdrug(ev){
    var self = this;
    var base = document.getElementById('codepane').offsetHeight;
    var startpos = mouse_y(ev);
    document.onmousemove = function(e) {
        if(!e){ e = event; }
        document.getElementById('codepane').style.height = (base + mouse_y(e) - startpos) + "px";
    };
    document.onmouseup = function(e) {
        if(!e){ e = event; }
        document.onmousemove = null;
        document.onmouseup = null;
    };
}   
function output_response(resp) {
    document.getElementById('output').innerHTML = '';
    
    var iframe = document.createElement('IFRAME');
    iframe.style.border="solid 1px #CCC";
    document.getElementById('output').appendChild(iframe);
    iframe.width = iframe.height = "99%";
    var ifdoc = frames[frames.length - 1].document;
    frames[frames.length - 1].frameBorder = "no";
    if(!document.getElementById('fullhtml').checked) {
        resp = "<html><body><pre>" + resp + "</pre></body></html>"
    }
    ifdoc.open(); ifdoc.write(resp); ifdoc.close();
}
window.onload = function() {
    var evalit = document.getElementById('evalit');
    evalit.onclick = function () {
        var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
        var cp = document.getElementById('codepane');
        cp.disabled = true; evalit.disabled=true;
        xhr.open('POST', location, true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                var resp = xhr.responseText;
                cp.disabled = false; evalit.disabled=false;
                output_response(resp);
            }
        };
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send("code=" + escape(cp.value).replace(/\+/g,"%2B") +
            (document.getElementById('fullhtml').checked ? "&fullhtml=1" : ""));
    };
    window.onload = null;
}
</script></head>
<body style="margin:0px;"><table width="98%" height="95%" cellpadding="0" cellspacing="0" border="0" style="margin:6px;"><tr><td>
<h1>PHP code snippet tester via eval.</h1>
<form method="POST">
    <textarea id="codepane" name="code" style="width:100%;height:200px;"><?php echo isset($_POST['code']) ? $_POST['code'] : ""; ?></textarea><br />
    <div onmousedown="startdrug(event);" style="background:#DDD;font-size:12px;white-space:nowrap;" align="right">Grab this bar to expand the testarea avobe.</div>
    <button id="evalit" type="button" />eval it!</button><input id="fullhtml" name="fullhtml" type="checkbox" value="1"> as HTML
</form>
</td></tr><tr><td id="output" height="90%" align="center"></td></tr>
</table></body></html>

サーバに何でもできるバックドアを作るってことなので、取り扱いは厳重注意でお願いします。