I am running an API on a EC2 Linux instance. I try to to execute a Python script from a PHP file. The path to the PHP file is /var/www/html/droptop/api/event/test.php. The path to the Python script is /var/www/html/droptop/blacklist/profanity.py. The Python script recieves two strings and checks whether one of these two strings contain objectionable content via Profanity Check. Then it returns 0 if no objectionable content was found, otherwise it returns 1. However, shell_execalways seems to return NULL. Profanity Check needs Python 3 to work properly.

When executed on command line, the PHP file and Python script perfectly work fine together.

I assume it has something to do with the user's permissions. apache and not www-data user is executing the files. However, I also changed the sudoers file according to here. I included following lines:

apache ALL=NOPASSWD:/var/www/html/droptop/blacklist/profanity.py
apache ALL=NOPASSWD:/usr/bin/python3.6

I also checked if apache is part of groups which it is.

I also tried other functions like exec(), system() or passthru().

Still it always returns NULL.

test.php

$command = escapeshellcmd('python3 /var/www/html/droptop/blacklist/profanity.py Some BadWord');
$output = shell_exec($command);

if($output == 0) {
  echo json_encode(array("message" => "No Badword found."));
}

profanity.py

#!/usr/bin/python36

from profanity_check import predict, predict_prob
import sys

# get title
title = sys.argv[1]
pred_title = predict([title])
pred_details = 0

if(len(sys.argv) == 3):
    details = sys.argv[2]
    pred_details = predict([details])

if((pred_title == 0) and (pred_details == 0)):
    print(0)
else:
    print(1)

What could be the problem here?

1 Answers

0
HTF On

You should remove these sudoers entries, they shouldn't be necessary in your case and it's a security risk.

I would also recommend to not relay on the output and use the exit status instead:

test.php

<?php
$command = escapeshellcmd('python3 /var/www/html/droptop/blacklist/profanity.py Some BadWord');
exec($command, $output, $return_var);

//echo $output;

if(!$return_var) {
  echo json_encode(array("message" => "No Badword found."));
}
?>

profanity.py

import sys

from profanity_check import predict


def profanity(words):
    return predict(words)

def main():
    words = sys.argv[1:]
    ret = profanity(words)
    sys.exit(any(ret))

if __name__ == '__main__':
    main()

Now, back to your original issue, the docs says

This function can return NULL both when an error occurs or the program produces no output.

You can un-comment the //echo $output; line and assuming you're using Apache web server running as apache user you can try to run the command below, hopefully this will give you some clue:

$ runuser -l apache -s /bin/bash -c "php -f /var/www/html/droptop/api/event/test.php; echo"
{"message":"No Badword found."}

Possible issues:

  • your python installation is not in the $PATH for apache user

  • profanity_check module is not installed globally