You are not logged in.

#1 2009-11-28 08:40:03

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

[Bash] Absolutely secure `source'?

Say I want to source another file in my script, but I want it to only allow variable assignment in that sourced file. Yes, I'm talking about sourcing a configuration file.
Though I think there's no reason for it since bash starts up sourcing ~/.bashrc, which, in my opinion, already makes it not that secure, I still want to know if there is a way to do "absolutely secure source".

It may seem not that tricky at first thought, but yes, it is. Just some random examples:

A_b=1 echo I am dangeraous
output="~/fo;o/love\"%deatch potato.mkv\\" ; echo I am a mess
subshell="$(echo funky stuff >&2)"

Solutions I imagine:
1. Some bash setting that will make life easy:

... ...
# some switch that makes bash retarded and only able to do variable assignment, nothing more.
source $CONFIG
# turn off that switch to bring bash back to normal
... ...

2. Allow only the format: wo_rd='anything that will stay dumb inside these two single quotes' in the actual sourced file.

grep -E "^ *\w+='([^']*(([^']{5})|('\"'\"'))*[^']*)*' *( +#.*)*$" $CONFIG > $TEMPCONFIG
source $TEMPCONFIG

The ([^']{5})|('\"'\"') part is to allow single quotes in the VALUE (KEY='VALUE', e.g. output='Mummy'"'"'sCar.foo' will assign $output as Mummy'sCar.foo)

I really prefer the first solution, if it is possible. If not, any thoughts on solution two are very welcome too. And more solutions are always more than welcome.

Regards

Last edited by lolilolicon (2009-11-28 08:53:22)


This silver ladybug at line 28...

Offline

#2 2009-11-28 09:57:09

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: [Bash] Absolutely secure `source'?

I think grep -o would be easier to use, not really sure if this helps:

--> cat source.txt 
echo test
a=5 echo hack
a="5 echo hack"
a=test2
echo $a
b=1
echo $b; b=2; echo $b
a='2134234'
b="13123123"
c=$(echo 12391230)
d="$(echo a b c d e)"
e="a b"'c d'
--> grep -o '[[:alpha:]]*=[^;]*' source.txt | grep -vF $'$(\n`' | sed -n 'h;s/\(['\''"]\)[^\1]*\1//g;tignore;:ignore;s/ //;t;g;p'
a="5 echo hack"
a=test2
b=1
b=2
a='2134234'
b="13123123"
e="a b"'c d'

BTW you don't need a temporary file, just use: eval $(grep ...)

Learned something about sed too: with several s/// commands in a row, the branch commands work even if only one of the s/// commands worked (the manual doesn't say it very clearly) so tignore;:ignore is necessary.

Offline

#3 2009-11-28 11:07:20

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: [Bash] Absolutely secure `source'?

Yeah I think `eval $(grep ...)' will do the same thing as `source $tempconfig', I wrote that because I always stay on topic tongue

I honestly don't quite understand the command due to my lack of sed knowledge.

The grep -vF $'$(\n`' is very nice to know, never seen that before smile

Anyway, I'm reporting back:

foo="fo o\"bar"
fo_O='fo o;bar'

Those two lines all get filtered out, which I think should not. And fo_O='fo o;bar' becomes O='fo o with just the grep part.

I think I'll learn sed better sometime soon. And to be on topic, I'm stilling sticking to method 2, now the command is

grep -E "^ *\w+=('([^']*(([^']{5})|('\"'\"'))*[^']*)*')?( *[; ]? *\w+=('([^']*(([^']{5})|('\"'\"'))*[^']*)*')?)* *( +#.*)*$" config.conf

It allows SINGLE quotes around value only:

>>> cat ss.txt
foo_bar='$(funky go dumb)`'
single='Sherlie'"'"'s Quote' #comments are fine, '"'"' inside single quotes means '
double="double quoted" # this is doomed
>>> grep -E "^ *\w+=('([^']*(([^']{5})|('\"'\"'))*[^']*)*')?( *[; ]? *\w+=('([^']*(([^']{5})|('\"'\"'))*[^']*)*')?)* *( +#.*)*$" ss.txt
foo_bar='$(funky go dumb)`'
single='Sherlie'"'"'s Quote' #comments are fine, '"'"' inside single quotes means '

Is everything (except single quote itself) inside single quotes never expanded (and thus safe)?

Last edited by lolilolicon (2009-11-28 11:37:07)


This silver ladybug at line 28...

Offline

#4 2009-11-28 11:48:44

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: [Bash] Absolutely secure `source'?

The sed command tests for spaces outside of "....." and '....' by removing those parts and then using s/ //;t, where t branches to the end if the s/// was successful, or if there aren't spaces restoring the backup.

And yeah inside single quotes is safe. Maybe you can even change lines to use single quotes if they don't already have them.

Offline

#5 2009-11-28 15:40:35

tlvb
Member
From: Sweden
Registered: 2008-10-06
Posts: 297
Website

Re: [Bash] Absolutely secure `source'?

Adding another suggestion, which limits what characters can be in the file.
The characters allowed in the example are alphanumerics, slash, equal sign and newline, for it to work at least equal sign and newline needs to be
allowed, because of them being a part of variable assignment and command separation respectively.

$ cat > config_file
foo=bar
f00=$(rm -rf /)
^C
$ IFS='\n';for i in $(cat config_file); do eval $(echo $i | tr -dc '[:alnum:]/=\n'); done;IFS=' ' # this is the important bit, the other stuff is example setup
$ echo $foo
bar
$ echo $f00
rmrf/

Last edited by tlvb (2009-11-28 15:43:23)


I need a sorted list of all random numbers, so that I can retrieve a suitable one later with a binary search instead of having to iterate through the generation process every time.

Offline

Board footer

Powered by FluxBB