The BICsuite Run Program Part 6: Security Considerations and Conclusion

Although, as we’ve seen, the run program on itself is a powerful feature, it is not without risks. Code injection
is the appropriate keyword here. Just imagine a run program like the following has been configured:

run program = /bin/bash -c "ls -l $DIRSPEC"

And that DIRSPEC is a parameter of type parameter. That means that if someone has operating privileges
for that job, that person is able to change the contents of the DIRSPEC parameter. Hence, it wouldn’t be a
problem at all to change the value from, let me assume ”/tmp”, into ”/tmp; cat /etc/passwd”. All of a
sudden the contents of the /etc/passwd file will be copied to stdout and will be readable for everyone who
is able to read the job’s log file. Needless to say, other, more dangerous commands, can be added as well,
basically even entire scripts.

In order to prevent such break-in attempts it is crucial to define the parameters to be of type constant instead of parameter. The type import is fine too, as long as it imports a parameter of type constant.

Parameters that are defined at folder, scope or resource level can be considered safe too. Resource parameters can be modified by jobs, if it is a synchronizing resource and the job allocates it with an exclusive lock. Theoretically an indirect attack can be constructed by setting the value to something offensive.

Obviously that’s not always possible. In such cases it’ll be crucial to test for the contents of a parameter. In
our example, the contents of DIRSPEC have to be tested if it refers to an existing file or directory. For the
sake of the example, let’s assume that DIRSPEC is an imported parameter from elsewhere, where it is defined
as a parameter of type parameter.

By changing the run program to

run program = /bin/bash -c "$MY_LS_SCRIPT"

and creating the constant MY_LS_SCRIPT with a content like

if [ -e "$X" ]; then
    ls -l "$X";
    echo "File ’$X’ not found or invalid";
    exit 1;

we’ve improved our ls command in a way that simple attacks won’t work any more.

But we’re still far away from safety. The problematic statement now is the assignment of the value of DIRSPEC
to the shell variable X. We need to realize, that the variable substitution by the scheduling system is done before the bash script is handed over to the shell. Hence if we change our job as outlined above, it’ll be sufficient to set the value of DIRSPEC to something like /tmp"; cat "/etc/passwd the assignment of the parameter value to X, will cause the shell to execute execute

X="/tmp"; cat "/etc/passwd"

Again the contents of the /etc/passwd file are copied to stdout.

It is worth to analyse this a little closer. We have a command line that is modified (scheduler variables/- parameters are resolved) in the process of preparing the job for execution. At this time, parameters can’t be checked yet. But after the replacement there’s no way of distinguishing original code from freshly added code.

If we compare the shell as a command interpreter with some scripting language, e.g. Python or Perl, we will find that the security problems are suddenly greatly reduced. To show this, we use a Python utility that does nothing more than an ls -l and uses an argument to know which directory should be listed.

The Python script could look like this:

import os
import sys
accperm = {0 : ’---’, 1 : ’--x’, 2 : ’-w-’, 3 : ’-wx ’,
           4 : ’r--’, 5 : ’r-x’, 6 : ’rw -’, 7 : ’rwx ’ }
def print_details (f):
    stats = os. stat (f)
    print str (f) + ’\t’ + accperm [( stats . st_mode /64)%8] + \
                           accperm [( stats . st_mode /8)%8] + \
                           accperm [( stats . st_mode %8)] + \
                    ’\t’ + str ( stats . st_size /1024) + ’K’
my_path = ’/ tmp ’
if len ( sys . argv ) > 1:
    my_path = sys. argv [1]
os. chdir ( my_path )
files = os. listdir ( my_path )
for f in files :
    print_details (f)

Even with limited knowledge of Python, it is obvious that the script will list the files in /tmp if no arguments
are specified, otherwise it will list the files of the specified directory (if it exists).

When using this in a BICsuite environment, the run program could look like this:

run program = /usr/bin/python -c "$PYTHONLS" "$DIRTOLIST"

PYTHONLS is a parameter (constant) that provides the above script, and DIRTOLIST is a parameter that specifies the directory to process.

In case of using the bash, this would leave the doors wide open for code injection. But in our Python example, this is not that easy, if at all possible in the first place. The parameter PYTHONLS is a constant and cannot be exploited. The other parameter, DISTOLIST, can be manipulated. However, that’s not that easy, even if we didn’t write any code to inspect the value from outside. The parameter is used as an argument of os.chdir() and it is very likely, that this standard Python function simply passes its argument on to the underlying system call. The underlying system call probably won’t find any directory with the (manipulated) value of DIRTOLIST and will fail, just as the os.listfiles() call. In this case it’s just a matter of adding some error processing code and the script can be considered to be safe.


The conclusion of this paper is that BICsuite offers powerful features that allow scripts to be stored within the scheduling system and executed.

If modifiable parameters are used in combination with a shell as the command interpreter, it will be impossible or at least difficult to prevent code injection attacks, due to the nature of shells. Hence either such jobs have to be eliminated, or it has to be guaranteed that only highly privileged persons can submit and/or operate such jobs.

If other command interpreters are used, the situation is a lot more relaxed and security can be ensured with moderate effort.

Part 1: Introduction and simple usage

Part 2: Advanced usage

Part 3: Backticks

Part 4: Other interpreters

Part 5: Circumventing limitations

Part 6: Security considerations and conclusion