Mika H.
Mika H.

Reputation: 4339

Prevent injection via URL input

In my Rails controller, I take a URL that the user inputs and runs the system command wget:

system("wget #{url}")

I'm afraid that the user might put in something like www.google.com && rm -rf ., which would make the controller execute the command

system("wget www.google.com && rm -rf .")

which deletes everything. How should I prevent against this kind of attacks? I'm not sure what other things the user could put in to harm my system.

Upvotes: 2

Views: 665

Answers (3)

kp2222
kp2222

Reputation: 94

If all you want to do is to just retrieve the content of the URL, it is better to completely avoid the use of 'system' or any other means of running a command on the server.

You can use an http client such as Httparty to fetch the URL content.

response = HTTParty.get("#{url}")

Upvotes: 2

Chris Heald
Chris Heald

Reputation: 62668

Per this thread:

You can avoid shell expansion by passing arguments to the script individually:

system("/bin/wget", params[:url])

Per the documentation on Kernel#system this form does not invoke a shell. Constructs like && are shell constructs, so if you use this form, then the param will be passed to /bin/wget literally as an argument.

That said, still be suspicious of input, sanitize where possible, and if feasible, run it as a non-privileged (or better yet, jailed) user.

Upvotes: 3

Wyzard
Wyzard

Reputation: 34571

Joining commands together with && (or ;, or |) is a shell feature, not something that wget itself understands. If you're using a function that passes a command line to a shell (such as the system() function in many languages), you're at risk. If you execute the wget program directly (rather than executing a shell and giving it a command line), you won't be at risk of that particular attack.

However, the attacker could still do other things, like abuse wget's -O option to overwrite files. You'd be better off not using wget at all — if your goal is to download a file, why not just use an HTTP library to do it directly in your own program's code?

Upvotes: 2

Related Questions