Mike B
Mike B

Reputation: 151

Is there an easy way to santize user data going into a bash script?

I have a simple script that takes a subject-line and return-path from STDIN (a piped email) and runs custom curl query using the subject:

#!/usr/bin/env bash

# Check for the sender email address and subject.
# Assign them to variables for use later.
while read -r key value; do
    case $key in
        Subject:) subject=$value;;
        Return-Path:) return_path=$value;;
    esac
done

# Run a curl query utilizing a modified version of the subject (replacing spaces with plus symbols)

curl "https://foo.com/&q="${subject// /+}"" >> foo.txt

My concern though is that this leaves a hole for malicious (or accidental) use of problematic subject headers like: Subject: Test 123; rm -fr /;

Is there an easy way to prevent this from happening?

I apologize if this is a vague question. I'm very new to scripting so my knowledge of script hardening/sanitizing is very slim. If there is a beginner's reference for this, please let me know.


UPDATE. Here's the revised script:

#!/usr/bin/env bash

# Check for the sender email address and subject.
# Assign them to variables for use later.
while read -r key value; do
    case $key in
        Subject:) subject="$value";;
        Return-Path:) return_path="$value";;
    esac
done

# Run a curl query utilizing a modified version of the subject (replacing spaces with plus symbols)

curl "https://foo.com/&q=\"${subject// /+}\"" >> foo.txt

Upvotes: 0

Views: 154

Answers (3)

Jo So
Jo So

Reputation: 26501

I'm sorry to say that the currently accepted answer is wrong. As geirha pointed out, no need for quotes around assignments.

But change

curl "https://foo.com/&q=\"${subject// /+}\"" >> foo.txt

to

curl "https://foo.com/&q=${subject// /+}" >> foo.txt

There is no such thing as "apply two levels of quoting" unless of course you're running data through two shells.

Read sections 2.2.1 through 2.2.3 of the sh spec to get a good feeling for how quoting works. Also read 2.6.5 "Field Splitting" to understand how variables that are not in double quotes are split.

In no case is external input treated as a command can input "inject" a command, unless of course you trust it and are running it through another shell.

Upvotes: 1

geirha
geirha

Reputation: 6181

curl can urlencode that for you.

while read -r key value; do
    case $key in
        Subject:) subject=$value;;
        Return-Path:) return_path=$value;;
    esac
done

curl --get --data-urlencode "q=$subject" "https://foo.com/" >> foo.txt

No matter what the subject contains, it will at no point be treated as code.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798676

Yes. Always use quotes. ALWAYS.

foo="$bar"

Upvotes: 3

Related Questions