Reputation: 151
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
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
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