image
image

Go Back   macosx.com > Design, Media, Programming & Scripting > Software Programming & Web Scripting

Reply
 
LinkBack Thread Tools
  #1  
Old February 6th, 2009, 12:22 PM
Mikuro's Avatar
Crotchety UI Nitpicker
 
Join Date: Mar 2005
Posts: 2,682
Thanks: 6
Thanked 53 Times in 48 Posts
Mikuro will become famous soon enough
Question Sanitizing shell arguments in Python

For the past day I've been wringing my hands trying to figure out the best way to pass a string variable in Python as an argument to a shell command.

I can't just do this:
Code:
input, output, error = os.popen3("echo " + my_var)
Because if my_var contains, let's say, "'Lala-la'; rm -rf /", then it would delete all my files. It's obviously not safe, so I need to sanitize the input. Fair enough.

AppleScript has a "quoted form of ..." method that's useful for this, but I can't find any equivalent in Python (or Perl, which I also considered for this project).

So, I have two questions:

1. Is there a standard way of doing this that I'm not aware of? Perhaps a shell command that operates on stdin?
2. If I need to write my own function, would it be as simple as replacing all instances of "\" with "\\", replacing all instances of "'" with "\'", and then wrapping the result in single-quotes? i.e.,
Code:
def sanitize_arg(arg):
	return "'" + arg.replace('\\','\\\\').replace('\'','\\\'') + "'"
I don't see why that would be a problem, but....aren't those famous last words?

In my Google searching on the topic I've found lots of people like me reinventing the wheel, but I haven't found any authoritative answer. A lot of the sample code I found doesn't even escape backslashes, or just uses string formatting (which as far as I can tell doesn't filter the input at all). Ack!
__________________
Mac mini — 1.25GHz G4, 1GB RAM — OS 10.5.8

Useful programs: Privoxy, Butler, ffmpegX, VLC, Perian, Tofu, Wcalc

Last edited by Mikuro; February 6th, 2009 at 12:27 PM. Reason: Fixed typo in code snippet
Reply With Quote
  #2  
Old February 6th, 2009, 02:00 PM
Mikuro's Avatar
Crotchety UI Nitpicker
 
Join Date: Mar 2005
Posts: 2,682
Thanks: 6
Thanked 53 Times in 48 Posts
Mikuro will become famous soon enough
Never mind, I found the solution. Replace this:
Code:
put, get, err = os.popen3("echo " + my_var)
With this:
Code:
put, get, err = os.popen3(["echo", my_var])
If you supply just one string, Python sends it to the shell for interpretation, but if you supply a LIST of strings, then it will take the first entry as the command name and each subsequent entry as an argument. No need to muck around with manual escaping.

As a test I ran this:
Code:
import os
my_var = "'Lala-la'; mkdir /Test"
put, get, err = os.popen3(["echo", my_var])
put.close();
print get.read()
get.close()
err.close()
Which outputs "'Lala-la'; mkdir /Test". Problem solved.

Oh, and also, it looks like os.popen* is deprecated and I'm supposed to use the subprocess module instead. It appears to work the same way (in fact, that's how I discovered that I could use a list in the first place; they don't mention it on the documentation for os.popen*, but they mention it under subprocess).

I hope this will help future Googlers.
__________________
Mac mini — 1.25GHz G4, 1GB RAM — OS 10.5.8

Useful programs: Privoxy, Butler, ffmpegX, VLC, Perian, Tofu, Wcalc
Reply With Quote
  #3  
Old February 7th, 2009, 12:42 AM
Registered User
 
Join Date: Feb 2009
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Paddy3118 is on a distinguished road
Sanitize on input

Hi,
A useful way to create programs is to sanitize all data on input, then you can treat it as OK for any output. Having said that, the advice to use subprocess with multiple arguments is sound.

- Paddy.
Reply With Quote
Reply

Bookmarks

Tags
argument, escape, python, sanitize, shell

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Forum Jump


All times are GMT -5. The time now is 02:57 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC1
Copyright 2000-2010 DigitalCrowd, Inc.