Command injection possible with subprocess shell=False? - python-3.x

I have an API which, long story short, runs a custom command on a remote machine (I'll call it custom_command). The app is run via subprocess with shell=False. The command is run and arguments may be programmatically appended to it based on input to an API. IE:
End-user runs curl https://rest-api-address -d {"add_do_this": true}
Server runs subprocess.Popen(["custom_command", "--do-this"], shell=False)
The end users have asked for the ability to append custom arguments when invoking the command by entering a raw string, ie:
curl https://rest-api-address -d {"add_do_this": true, "custom_args": "--custom-arg1 val1 --custom-arg2 val2"}
Server runs subprocess.Popen(["custom_command", "--do-this", "--custom-arg1", "val1", "--custom-arg2", "val2"], shell=False)
I'm reluctant to allow them to enter a raw string b/c of command injection fears, but if I take the string, shlex.split it, and extend the original command, is there still a risk of injection if shell=False? Or any other security risk? The documentation seems to imply no and I haven't been able to create one in my testing, but something about this feels risky, and I'm not sure if I'm being too paranoid.
https://rest-api-address -d {"add_do_this": true, "custom_args": "--custom-arg1 val1;echo 'HAHA' --custom-arg2 val2"}
Did not cause injection

Related

Text in Bash terminal getting overwritten! Using JS, Node.js (npms are: inquirer, console.table, and mysql)

Short 10sec video of what is happening: https://drive.google.com/file/d/1YZccegry36sZIPxTawGjaQ4Sexw5zGpZ/view
I have a CLI app that asks a user for a selection, then returns a response from a mysql database. The CLI app is run in node.js and prompts questions with Inquirer.
However, after returning the table of information, the next prompt overwrites the table data, making it mostly unreadable. It should appear on its own lines beneath the rest of the data, not overlap. The functions that gather and return the data are asynchronous (they must be in order to loop), but I have tried it with just a short list of standard synchronous functions for testing purposes, and the same problem exists. I have tried it with and without console.table, and the prompt still overwrites the response, as a console table or object list.
I have enabled checkwinsize in Bash with
shopt -s checkwinsize
And it still persists.
Is it Bash? Is it a problem with Inquirer?
I was having this issue as well. In my .then method of my prompt I was using switch and case to determine what to console log depending on the users selection. Then at the bottom I had an if statement checking to if they selected 'Finish' if they didn't I called the prompt function again, which I named 'questionUser'.
That's where I was having the issue, calling questionUser again was overriding my console logs.
What I did was I wrapped the questionUser call in a setTimeout like this:
if(data.option !== 'Finish'){
setTimeout(() => {
questionUser();
}, 1000);
}
This worked for me and allowed my console log data to not get deleted.
Hopefully if anyone else is having this issue this helps, I couldn't find an answer to this specific question anywhere.

Linux Command Output to Chef Attribute

The issue is I need to assign the value of Linux command to CHef Attribute.But unable to do it.
Im using the below code and not finding the result. Kindly Help what im
missing
ruby_block "something" do
block do
Chef::Resource::RubyBlock.send(:include, Chef::Mixin::ShellOut)
node.default['foo'] = shell_out("echo Hello world").stdout
end
action :create
end
log "demo" do
message lazy { node['foo'] }
end
Below is the Run logs:
Starting Chef Client, version 13.9.1
resolving cookbooks for run list: ["sample_repo"]
Synchronizing Cookbooks:
- sample_repo (0.1.4)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 2 resources
Recipe: sample_repo::default
* ruby_block[something] action create
- execute the ruby block something
* log[demo] action write
Running handlers:
Running handlers complete
Chef Client finished, 2/2 resources updated in 02 seconds
Thanks in advance
Your code is fine, the log message is not showing because the default level on the log resource is :info and by default chef-client doesn't show info-level log messages when run interactively. That said, this kind of code where you store stuff in node attributes is very brittle and probably shouldn't be used unless specifically needed. Better is to do this:
message lazy { shell_out("echo Hello world").stdout }
Also you don't need any funky mutating include stuff like you there AFAIK, the shell_out helpers are available in most contexts by default. Also you should usually use shell_out!() rather than shell_out(), the ! version automatically raises an exception if the command fails. Unless you specifically want to allow a failed command, use the ! version.

get the output of the remote execution of the SSH command

I work with expressJs and to execute a remote SSH command I use the 'simple-ssh', this code allows to execute the command except that I could not get the result of the display outside this block.
ssh.exec('ls Documents/versions', {
out: function(stdout) {
arrayOfVersion = stdout.split("\n");}}).start();
How to get the content of arrayOfVersion and manipulate it after
Your function which creates arrayofVersion async, you won't be able access it outside of this scope without some sort of waiting process which waits until the variable has a value.
You can do this in a few ways, to begin with I would recommend researching how nodejs handles async functions as this is a big part of nodejs. Generally you would use one of the following: callbacks, promises, or async/await.
With any of those techniques, you should be able to run your SSH code and then continue on with the result of the stdout.

Executing REDIS Command in Node.js

I am writing a Node app. This app interacts with a REDIS database. To do that, I'm using node_redis. Sometimes, I want to just execute a command using a line of text. In other words, I want to do a pass through without using the wrapper functions. For instance, I may have:
set myKey myValue
I would LOVE to be able to just execute that without having to break apart the text and call client.set('mykey', 'myValue'); Is there a way to just execute a command like that against REDIS in the Node world? If so, how?
Thanks!
You should be able to use client.send_command(command_name, args, callback) to send arbitrary commands to redis. Args can be empty and so in your case you would just call client.send_command('set myKey myValue', null, cb).

No connection as non root using Net::SFTP::Foreign

I am trying to use a perl script to transfer files from one machine to another within a cron job. However for security reasons the cron job has to run as a unprivileged user. Now if I try to establish a connection using this unpriviliged user, Net::SFTP::Foreign always refuses to connect. Here is the part of the script I am having trouble with:
my $host = "hostname";
my %args = (
user => "username",
password => "password",
port => '12345'
);
my $sftp_connection = Net::SFTP::Foreign->new($host, %args);
if( $sftp_connection->error ) {
log_message( "E", "Error " . $sftp_connection->status() . " connecting to " . $host );
die;
}
log_message( "A", "Connected" );
I cannot give a full example, as this would require username and password.
If I execute this script as root, everything works fine, however if I try to use another user, the connection always fails.
Is there a way to get some more diagnostic information? I think there was a way to get more output from the actual sftp process, but I cannot look it up right now as cpan currently does not work from here.
I previously also tried using Net::SFTP instead of Net::SFTP, but the error handling at later parts did not work correctly, so switching to Net::SFTP does not seem a viable option right now.
Use metacpan.org
Debugging:
For debugging purposes you can run ssh in verbose mode passing it the -v option:
my $sftp = Net::SFTP::Foreign->new($host, more => '-v');
"Module description"
Enabling debugging (thanks to all commenters), I could see that the host-key verification failed. So after I added the key to the list of allowed keys (by doing a manual ssh to the host once), everything worked fine.
For root the key must have been in the list already, so that it had nothing to do with priviledge, just with prior usage of the account (I seem have ssh'ed before from root to the other host).

Resources