Is it possible to get the exact raw command line in PHP as typed in?
$ ./example.php --key1="value" --key2='value' --key3= value-with-leading-double-blank
I'd like to now if value was enclosed in single or double quotes and if any blanks were typed. Obviously implode(' ', $argv[]) does not work as surrounding quotes and blanks have been stripped already.
Any hints?
Related
I've got some powershell that connects to my server and returns an address to be passed to a batch file.
This batch file is a requirement, as it's an HTA/Batch Hybrid that allows me to run a created UI for the project. The URL is being passed as an iframe source to load some results from the server.
I have a variable $content in powershell, which equals http://example.com/selectMultiple.php?choice=[{"id":51,"p":100},{"id":52,"p":94}] (Slightly modified to protect my server address)
I then launch the batch file, while passing that $content variable to it like this
"Launching $content"
Start-Process "files\hybrid.bat" "$content"
In the batch file I have some code that echo's the value that was passed to it.
set "link=%~1"
echo %link%
But after being passed, some of the variable is trimmed. This echos http://example.com/selectMultiple.php?choice - which leads me to believe that there is something with the = sign that is breaking the string.
I've tried urldecode methods in powershell and from my server (php) and neither fixed the issue.
I am at a loss here and would much appreciate any help resolving this issue./
(I tagged PHP as well, to show that I do have the ability to work with the code that is returning the URL)
Start-Process "files\hybrid.bat" """$content"""
Note that $content variable contains characters (e.g. = and ,) which are treated as parameter delimiters in batch scripting:
Delimiters separate one parameter from the next - they split the
command line up into words.
Parameters are most often separated by spaces, but any of the
following are also valid delimiters:
Comma (,)
Semicolon (;)
Equals (=)
Space ( )
Tab ( )
The called batch (see set "link=%~1" command) strips the first supplied parameter from enclosing double quotes in the right way. Hence, you need to pass the string from $content variable enclosed in double quotes from powershell. Use doubled inner double quotes as follows:
# ↓ ↓ string delimiters are not supplied
Start-Process "files\hybrid.bat" """$content"""
# ↑↑ ↑↑ escaped inner double quotes are supplied
Double-Quoted Strings (")
When you enclose a string in double quotation marks, any variable
names in the string such as "$myVar" will be replaced with the
variable's value when the command is processed. … Any embedded
double quotes can be escaped using the grave-accent as `" or
doubled (replace " with "").
I'm trying to know the list of artisan command by using php artisan list . and the command return me the following error
[Dotenv\Exception\InvalidFileException]
Dotenv values containing spaces must be surrounded by quotes.
What is wrong?
Thanks in advance.
You should remove all spaces from .env file to make an app work again.
If you have to use spaces, instead of this:
VAR=some data
Use quotes:
VAR="some data"
Verify your .env file. You need to check for the following:
Any extra or non-needed spaces
If you have any strings with spaces, make sure to surround them in quotes
Example:
varaible=123 Test
Needs to be
varaible="123 Test"
Make sure that:
all variables with spaces are surrounded by quotes
there are no semi-colons
if you use two word for username or database name in .env,put it inside a double quotation.
First check env.
If your var value with space so check value in double quotes. like,
MAIL_FROM_NAME="Sarvajanik School"
If you use single quotes then the possible to got this error containing spaces must be surrounded by quotes
I'm trying to create a PHP script that creates a file on a remote linux server through ssh, and echos the file contents into it.
However, I cannot figure out how to correctly and safely encode/escape the file contents, so that the contents don't get interpreted as commands.
I'm using phpseclib from here.
I've tried something like
echo $ssh->exec('sudo echo "' . escapeshellarg($newConfig) . '" > /etc/nginx/nginx.conf') . "\n";
but without success.
Thanks,
Steve
What about escapeshellcmd? Quoting the description of that vs escapeshellarg:
escapeshellarg() adds single quotes around a string and quotes/escapes
any existing single quotes allowing you to pass a string directly to a
shell function and having it be treated as a single safe argument.
...and...
escapeshellcmd() escapes any characters in a string that might be used
to trick a shell command into executing arbitrary commands. This
function should be used to make sure that any data coming from user
input is escaped before this data is passed to the exec() or system()
functions, or to the backtick operator.
Following characters are preceded by a backslash: #&;`|*?~<>^()[]{}$\,
\x0A and \xFF. ' and " are escaped only if they are not paired. In
Windows, all these characters plus % are replaced by a space instead.
I was going about this all wrong, I should have used Net_SFTP instead of NET_SSH for this sort of thing.
I'm running into an issue with the function str_replace() while trying to create a shell command in PHP. In shell, when I tab-finish a line that has spaces, it comes up like this:
tar cvfz destination/filename.zip source/Name\ Of\ The\+\ Folder
So to me, this says that in order to run this command via exec(), I need to replace any spaces I would have in a string in PHP. To remedy this problem, I'm using
$q = str_replace(' ', '\ ' , $q);
at the start of my string parse, in order to format the spaces into "\ " instead of " ". The issue I'm having is that for this particular folder, it's also removing the plus symbol as well, and it formats it like this:
tar cvfz destination/Name\ Of\ The\ \ \ Folder.tgz source/Name\ Of\ The\ \ \ Folder
How can I set this up so str_replace() doesn't remove the plus sign? From my limited tests so far, it isn't removing anything out of these: -, %, #, !, (, *, ), ^, =
Using string functions for this is very wrong and likely to leave security holes wide open.
PHP has a function called escapeshellarg() that does exactly what you need:
escapeshellarg() adds single quotes around a string and quotes/escapes any existing single quotes allowing you to pass a string directly to a shell function and having it be treated as a single safe argument. This function should be used to escape individual arguments to shell functions coming from user input.
I'm executing the following in a PHP application:
$source = '/home/user/file.ext';
$output_dir = $this->setOutputString();
chdir('/home/ben/xc/phplib/bgwatcher-2011a/a01/');
exec('php bin/createjob.php $source $output_dir', $output);
return $output[0];
The problem is this: I have control over $source, but not $output_dir, which is a legacy Windows filesystem, and there are spaces in the path. An example $output_dir is:
/home/vol1/district id/store id/this_is_the_file.html
When inserting the output string into the exec() function, I have tried both:
addslashes($output_dir) and '"' . $output_dir . '"' to escape the entire output string. In the first case, the path gets concatenated to:
/home/vol1/districtthis_is_the_file.html
... where everything between the first space and the filename gets dropped. In the second case, exec() appears to throw a shoe and doesn't execute properly - unfortunately, the error message is getting lost in the machinery - I can provide it if it's absolutely necessary, but I'm also under time constraints to find a solution.
What's the solution, here? Do I sprintf() the entire string for exec()? I'm very confused as to why addslashes isn't working correctly to escape the spaces, and I assume it has something to do with sanitization with exec(), but I can't find any documentation to back it up.
Update: I've tried escapeshellarg() and preg_replace() without success. Thinking about this further, do I need to double-escape the path? Or escape the path and the command? If the path is being unescaped once by exec(), and once by PHP before it executes the command, does it stand to reason that I need to account for both escapes? Or is that not how it works?
I don't believe addslashes() does anything with spaces. escapeshellarg() might be what you want instead. Docs on escapeshellarg
From the PHP doc (here),
Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash () and NUL (the NULL byte).
This won't do anything to the spaces. What you will need to do is use str_replace() to add slashes, like this:
$new_string = str_replace(" ", "\\ ", $old_string);
According to the PHP docs,
Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash () and NUL (the NULL byte).
Looks like you'll have to preg_replace the spaces yourself.
Edit:
Even though this is the topic of another discussion, if performance is an issue, then after looking into it a little more, it seems that str_replace is actually quite a bit faster than preg_replace:
The test labeled "str_replace()" was
the faster by 0.9053 seconds (it took
10.3% the time.)
The first test took 1.0093 seconds. (preg_replace)
The second test took 0.104 seconds. (str_replace)
Benchmark found here.
I've used exec() with paths with spaces before, on both Windows and Linux hosts, and in both cases quoting the path worked perfectly for me.
That said, if you have no control over the safety of a shell argument, always run it through escapeshellarg() first!
You can very well use shell quotes, since that is what all exec commands run through:
exec("php bin/createjob.php '$source' '$output_dir'", $output);
It btw works not just for arguments, but also for the command itself:
exec('"/bin/echo" "one parameter"');
Use escapeshellcmd() anyway.
this works for me when using exec() with soffice(LibreOffice):
$file_name = "Some, file name.xlsx";
exec('/usr/bin/soffice --headless --convert-to pdf '."'".$file_name."'".' 2>&1', $output, $r);
You can use double quotes and escape character together to work out this.
$fileName = "filename with spaces.pdf";
exec("php bin/createjob.php >\"".$fileName."\" 2> error.log" , $output, $return);