You are not logged in.
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
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
Yeah I think `eval $(grep ...)' will do the same thing as `source $tempconfig', I wrote that because I always stay on topic
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
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
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
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