Python Web Server with PHP code? [duplicate] - php

For some reason, I have to run a php script to get an image from Python. Because the php script is very big and it is not mine, it will takes me days to find out the right algorithm used and translate it into python.
I am wonder if there is any way to run php script, with few parameters, which returns a image, in python.

Example code:
import subprocess
# if the script don't need output.
subprocess.call("php /path/to/your/script.php")
# if you want output
proc = subprocess.Popen("php /path/to/your/script.php", shell=True, stdout=subprocess.PIPE)
script_response = proc.stdout.read()

You can simply execute the php executable from Python.
Edit: example for Python 3.5 and higher using subprocess.run:
import subprocess
result = subprocess.run(
['php', 'image.php'], # program and arguments
stdout=subprocess.PIPE, # capture stdout
check=True # raise exception if program fails
)
print(result.stdout) # result.stdout contains a byte-string

You can use php.py. This would allow you to execute php code in python, like in this example (taken from here):
php = PHP("require '../code/private/common.php';")
code = """for ($i = 1; $i <= 10; $i++) { echo "$i\n"; }"""
print php.get_raw(code)

If you can run the PHP script locally from the command-line, subprocess.check_output() will let you can PHP and will capture the return value.
If you are accessing PHP via a socket, then you can use urllib.urlopen() or urllib.urlretrieve() to pull down the resource.

Make a wrapper around the PHP script, which:
performs the stuff (If I understand well, it's an image creation),
then redirects (301 Moved Permanently) to the result image,
(also, the image should be purged some day).
So you can refer to this service (the PHP script) with a simple HTTP request, from anywhere, you can test it with browser, use from Python prg, you need just download the image the usual way.
Also, if you have a such standalone sub-system, don't feel bad about implement it with different language/technique. It has several advantages, e.g. you can install that service on a different host.
Recommended reading: Service-Oriented Architecture on Wikipedia.

Related

Run script with subprocess.run() in Python, blocking all file read/write attempts

I have a web server running Apache 2 on Raspbian Stretch. It is going to be a programming contest website, where users can send code via a HTML form, that sends their source code to PHP via a POST request. PHP then runs (using exec()) a Python script with arguments such as the submitted code path. The script then executes the code (using subprocess.run()) with a custom input and compares it to an expected output. All of that works just fine.
However, I want to make sure no one is going to send malicious code to overwrite files such as index.php, or read the expected outputs, for example. I'd like to know if there is any way to prevent an application that is being executed by subprocess.run() from reading, creating and writing to files other than stdin, stdout and stderr.
I have tried using Docker but didn't have success, as when I build and run the Dockerfile using PHP's exec() it reaches step 2/4 and just stops. My Dockerfile should copy the script, the code and the expected outputs to an image, cd to the new location and execute the code, but that is not very relevant since I want to avoid Docker as it isn't working properly.
I am considering using a chroot jail, but I am still looking for other less-complicated ways of doing that.
This is the PHP code I'm using. It calls the Python 3 code verifier (variables are retrieved from a HTML form and from a SQL query, those are not relevant):
$cmd = "python3 verify.py $uploadedFile $questionID $uploadedFileExtension $questionTimeLimit 2>&1";
And this is the Python 3 code that executes the submitted code:
def runCmd(args, vStdin, timelimit = 10):
p = subprocess.run(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE, input = vStdin, encoding = 'utf-8', timeout=timelimit)
vStdout = p.stdout
vStderr = p.stderr
if vStdout.endswith('\n'):
vStdout = vStdout[:-1]
if vStderr.endswith('\n'):
vStderr = vStderr[:-1]
return vStdout, vStderr
...
# Assuming it is a .py file
# Its path is given by PHP's exec.
runCmd(['python3', sys.argv[1], 'simulatedinput.in', int(sys.argv[4]))
The combination of both programs works just fine. It runs the code with a simulated input, compares the stdout with the expected output and returns a status string to the PHP code. However, if the code sent has a malicious bit of code, such as
open('/var/www/html/contest/index.php', 'w').write('oops!')
the index.php file will be overwritten.
All I need is a way of executing the user-sent code in a way that its attempts to read or write to files (other than stdin, stdout and stderr) are denied.
Any thoughts?
doing this securely, to put it simply, is difficult. it's relatively easy to escape even a chroot jail if you're not really careful about how you set it up. basically the Unix security model isn't built to make this sort of thing easy and it's assumed that things are mostly cooperative
docker would probably be my suggestion, but there are other lighter weight solutions like chroot (but they'd probably still have the ability to do naughty things with the web server's network connection) or maybe something like firejail
with docker you'd probably want to create a single minimal docker image/container containing Python and whatever libraries are appropriate. you'd then use volumes to make the user supplied code appear inside the VM at runtime. you don't want to be creating containers all the time, that would entail lots of cleanup work
see https://security.stackexchange.com/q/107850/36536 for some more info on using docker as a sandbox, basically there are still lots ways out of it unless you're careful

How can I test Node.js code to the browser?

I used to use PHP in my projects and MySQL of course, but I'm starting a course to Node.js right now and I really don't understand how it works. In PHP all I ever needed was an Apache as localhost and MySQL.
But when I use Node.js, what do I need ? The main question is how and where I can implement and write Node.js code and how I test it on the browser like I used to do in PHP?
Node.js is a runtime for JavaScript code that is specifically not run in the browser. To execute JavaScript in Node.js, you simply run Node.js from the command line and supply your JavaScript source file as an argument.
node myFile.js
This will execute whatever is in myFile.js. This file could look like the following:
let myVar = 1;
for (myVar; myVar < 5; myVar++) {
console.log(myVar);
}
This would print the following to the command line, when run:
1234

Execute php code in Python

For some reason, I have to run a php script to get an image from Python. Because the php script is very big and it is not mine, it will takes me days to find out the right algorithm used and translate it into python.
I am wonder if there is any way to run php script, with few parameters, which returns a image, in python.
Example code:
import subprocess
# if the script don't need output.
subprocess.call("php /path/to/your/script.php")
# if you want output
proc = subprocess.Popen("php /path/to/your/script.php", shell=True, stdout=subprocess.PIPE)
script_response = proc.stdout.read()
You can simply execute the php executable from Python.
Edit: example for Python 3.5 and higher using subprocess.run:
import subprocess
result = subprocess.run(
['php', 'image.php'], # program and arguments
stdout=subprocess.PIPE, # capture stdout
check=True # raise exception if program fails
)
print(result.stdout) # result.stdout contains a byte-string
You can use php.py. This would allow you to execute php code in python, like in this example (taken from here):
php = PHP("require '../code/private/common.php';")
code = """for ($i = 1; $i <= 10; $i++) { echo "$i\n"; }"""
print php.get_raw(code)
If you can run the PHP script locally from the command-line, subprocess.check_output() will let you can PHP and will capture the return value.
If you are accessing PHP via a socket, then you can use urllib.urlopen() or urllib.urlretrieve() to pull down the resource.
Make a wrapper around the PHP script, which:
performs the stuff (If I understand well, it's an image creation),
then redirects (301 Moved Permanently) to the result image,
(also, the image should be purged some day).
So you can refer to this service (the PHP script) with a simple HTTP request, from anywhere, you can test it with browser, use from Python prg, you need just download the image the usual way.
Also, if you have a such standalone sub-system, don't feel bad about implement it with different language/technique. It has several advantages, e.g. you can install that service on a different host.
Recommended reading: Service-Oriented Architecture on Wikipedia.

PHP in python through bash

As I am messing around with Python, I wanted to write an application that would have its own web server. I am currently using a written code from this website for http server: Python Web Server and this is the direct link of the script
This script can handle html but I wanted to add php to it too. Since I know that in Ubuntu I can run php commands within the terminal, I wanted to implement the same logic to this script.
I added these lines:
import os
os.system('php '+filepath)
However my plan didn't go as well as planned... The "<? echo 'hello world'; ?>" that was in my test.php echoed the string to the terminal that ran the webserver.py and it only returned the output message "0" to the web browser.
Is there a way to capture the output of the php file into a string in bash so that I can make the python webserver script output that string with os.system ?
I'm using Ubuntu 11.10.
You can use getoutput from the commands package for this simple case.
from commands import getoutput
response = getoutput('php myscript.php')
You should eschew the use of os.system() in favor of the more modern subprocess module.
You might especially look at popen.communicate().

How can I pass a url or variable from Perl to PHP?

I have two existing scripts that work fine as individuals.
The main script is Perl. I wish to execute the PHP script from a sub in the Perl script.
Usually, the PHP script is just run via direct url e.g. http://me.com/phpscript.php?foo=bar
I would like to just call the PHP script from the Perl and pass the foo var so, I don't need to hit the PHP script with my browser to process the data.
I am not talented enough to rewrite the PHP script to Perl.
I tried exec("http://me.com/phpscript.php?foo=bar"); and include and system to no avail.
I have read and searched but, found only solutions to call Perl from PHP.
I really appreciate the great guidance I always fine here.
Seems like LWP::UserAgent should work for this scenario.
require LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
my $response = $ua->get('http://me.com/phpscript.php?foo=bar');
if ($response->is_success) {
print $response->decoded_content; # or whatever
}
else {
die $response->status_line;
}
You can directly run a php file if you add #!PathToPhp
./myscript.php
in that file using argc or argv or args you can get arguments passed to this file most basic is args
#!/bin/php
<?php
foreach($args as $key => $value){
echo "\n".$key.":".$value;
If the script is located on the local filesystem, you should be able to exec it directly using the php interpreter and the path to the file. To access it via the web, use the LWP package.
For example:
exec('/usr/bin/php', 'myscript.php', #arguments);
Note that command-line arguments are handled differently than URL arguments; your PHP script will probably need to be modified to use them correctly.
There is a CPAN package that aims to provide a bridge between PHP and Perl:
This class encapsulates an embedded PHP5 intepreter. It provides proxy methods (via AUTOLOAD) to all the functions declared in the PHP interpreter, transparent conversion of Perl datatypes to PHP (and vice-versa), and the ability for PHP to similarly call Perl subroutines and access the Perl symbol table.
The goal of this package is to construct a transaparent bridge for running PHP code and Perl code side-by-side.
Not sure how stable this is though. See
PHP::Interpreter
Integrating PHP and Perl

Categories