8

I'm considering the idea of a browser-based PHP IDE and am curious about the possibility of emulating the command line through the browser, but I'm not familiar enough with developing tools for the CLI to know if it's something that could be done easily or at all. I'd like to do some more investigation, but so far haven't been able to find very many resources on it.

From a high level, my first instinct is to set up a text input which would feed commands to a PHP script via AJAX and return any output onto the page. I'm just not familiar enough with the CLI to know how to interface with it in that context.

I don't need actual code, though that would be useful too, but I'm looking for more of which functions, classes or APIs I should investigate further. Ideally, I would prefer something baked into PHP (assume PHP 5.3) and not a third-party library. How would you tackle this? Are there any resources or projects I should know about?

Edit: The use case for this would be a localhost or development server, not a public facing site.

VirtuosiMedia
  • 52,016
  • 21
  • 93
  • 140
  • 1
    possible duplicate of [REPL Environment for the Web](http://stackoverflow.com/questions/5918670/repl-environment-for-the-web) – Ignacio Vazquez-Abrams Jul 19 '12 at 05:35
  • @IgnacioVazquez-Abrams - It's not a duplicate. I'm looking to build my own, not utilize a 3rd party tool. The only answer there specifically for PHP is phpsh, which is written in python, so that doesn't actually help me build it in PHP. – VirtuosiMedia Jul 19 '12 at 05:45
  • What if someone executes `unlink('/')`? – Cole Tobin Jul 21 '12 at 22:56
  • 2
    The code for [viper-7s codepad](https://github.com/Viper-7/Deployable-PHP-Codepad) is available on github. Might be a useful reference for you. – Leigh Jul 26 '12 at 15:49

4 Answers4

2

The basic version would be

  1. you scripts outputs a form with a line input
  2. The form action points to your script
  3. The script takes the input on the form and passes it to eval
  4. pass any output from eval to the browser
  5. output the form again

The problem is, that defined functions and variables are lost between each request.

Would you could to is to add each line that is entered to your session. Lets say

$inputline = $_GET['line'];
$_SESSION['script'] .= $inputline . PHP_EOL;
eval($_SESSION['script'];

by this, on each session a the full PHP script is executed (and of course you will get the full output).

Another option would be to create some kind of daemon (basically an instance of a php -a call) that runs on the server in the background and gets your input from the browser and passes the output.

You could connect this daemon to two FIFO devices (one for the input and one for the output) and communicate via simple fopen.

For each user that is using your script, a new daemon process has to be spawned.

Needless to say, that it is important to secure your script against abuse.

Alex
  • 32,506
  • 16
  • 106
  • 171
2

Call this function trough a RPC or a direct POST from javascript, which does things in this order:

  • Write the PHP code to a file (with a random name) in a folder (with a random name), where it will sit alone, execute, and then be deleted at the end of execution.
  • The current PHP process will not run the code in that file. Instead it has to have exec permissions (safe_mode off). exec('php -c /path/to/security_tight/php.ini') (see php -?)
  • Catch any ouput and send it back to the browser. You are protected from any weird errors. Instead of exec I recomment popen so you can kill the process and manually control the timeout of waiting for it to finish (in case you kill that process, you can easily send back an error to the browser);

You need lax/normal security (same as the entire IDE backend) for the normal PHP process which runs when called through the browser.

You need strict and paranoid security for the php.ini and php process which runs the temporary script (go ahead and even separate it on another machine which has no network/internet access and has its state reverted to factory every hour just to be sure).

Don't use eval(), it is not suitable for this scenario. An attacker can jump out into your application and use your current permissions and variables state against you.

oxygen
  • 5,891
  • 6
  • 37
  • 69
  • In this scenario, how would you remember the values of PHP variables? Would each file contain/execute all of the console code in memory? Also, I'm not sure that all of the security steps you mentioned would be applicable in my use case. I'm thinking of a downloadable app for use on a localhost or a dev server, not something open to the public. – VirtuosiMedia Jul 24 '12 at 21:15
  • You can set variables by assignment. Re-running the PHP file reassigns them... Wether its open to the public or not does not influence my answer. Your question does not mention "downloadable app", only browser CLI. This browser CLI requirement only hints at a over the internet kind of thing. Regardless, my answer is still runnable on localhost, what you bind to still does not influence the answer's validity. – oxygen Jul 24 '12 at 21:22
  • In case of an error, you should rollback to before the last line/command. – oxygen Jul 24 '12 at 21:24
  • I haven't had a chance to test this yet, but I think it gives me enough of an idea of how to approach it that I can make it work. Thanks. – VirtuosiMedia Jul 28 '12 at 21:24
  • You could combine the above with a `while(true){include("part.php") ;sleep(1))}` (in case of an error you still have to rollback the whole thing, which might not play well with operations which shouldn't be repeated) - of course the `include` would be conditioned. – oxygen Jul 29 '12 at 13:04
1

Recently I read about a PHP interpreter written in Javascript php.js, so you could write and execute PHP code using your browser only. I'm not sure if this is what you need in the end but it sounds interesting.

pwuertz
  • 1,325
  • 8
  • 15
1

We've tested some products at my university for ssh-accessing our lab servers and used some of the Web-SSH-Tools - they basically do exactly what you want. The Shell-In-A-Box-Project may be bound to any interpreter you like and may be used with an interactive php-interpreter, if desired (on the demo-page, they used a basic-interpreter). The project may serve as a basis for a true PHP-IDE. These have the advantage of being capable of interacting with any console-based editor as well (e.g. vi, emacs or nano), as well as being able to give administrative commands (e.g. creating folders, changing ownerships or ACLs or rebooting a service).

Mozilla also has a full-featured webbased IDE called Bespin, which is also highly extensible and configurable.

As you stated, that the page is not for the public, you of course have to protect the page with Authentication and SSL to combat session hijacking.

Lars
  • 5,757
  • 4
  • 25
  • 55