22
22
# Runs a student script in a safe execution environment.
24
# NOTE: This script currently disables cookies. This means students will be
25
# unable to write session-based or stateful web applications. This is done for
26
# security reasons (we do not want the students to see the IVLE cookie of
27
# whoever is visiting their pages).
28
# This can be resolved but needs careful sanitisation. See fixup_environ.
24
30
from common import studpath
315
322
# python-server-page
325
def fixup_environ(req):
326
"""Assuming os.environ has been written with the CGI variables from
327
apache, make a few changes for security and correctness.
329
Does not modify req, only reads it.
332
# Comments here are on the heavy side, explained carefully for security
333
# reasons. Please read carefully before making changes.
335
# Remove HTTP_COOKIE. It is a security risk to have students see the IVLE
336
# cookie of their visitors.
337
del env['HTTP_COOKIE']
339
# Remove DOCUMENT_ROOT and SCRIPT_FILENAME. Not part of CGI spec and
340
# exposes unnecessary details about server.
341
del env['DOCUMENT_ROOT']
342
del env['SCRIPT_FILENAME']
344
# Remove PATH. The PATH here is the path on the server machine; not useful
345
# inside the jail. It may be a good idea to add another path, reflecting
346
# the inside of the jail, but not done at this stage.
349
# Remove SCRIPT_FILENAME. Not part of CGI spec (see SCRIPT_NAME).
351
# PATH_INFO is wrong because the script doesn't physically exist.
352
# Apache makes it relative to the "serve" app. It should actually be made
353
# relative to the student's script.
354
# TODO: At this stage, it is not possible to add a path after the script,
355
# so PATH_INFO is always "".
357
env['PATH_INFO'] = path_info
359
# PATH_TRANSLATED currently points to a non-existant location within the
360
# local web server directory. Instead make it represent a path within the
362
(_, _, path_translated) = studpath.url_to_jailpaths(req.path)
363
if len(path_translated) == 0 or path_translated[0] != os.sep:
364
path_translated = os.sep + path_translated
365
env['PATH_TRANSLATED'] = path_translated
367
# CGI specifies that REMOTE_HOST SHOULD be set, and MAY just be set to
368
# REMOTE_ADDR. Since Apache does not appear to set this, set it to
370
if 'REMOTE_HOST' not in env and 'REMOTE_ADDR' in env:
371
env['REMOTE_HOST'] = env['REMOTE_ADDR']
373
# SCRIPT_NAME is the path to the script WITHOUT PATH_INFO.
374
script_name = req.uri
375
if len(path_info) > 0:
376
script_name = script_name[:-len(path_info)]
377
env['SCRIPT_NAME'] = script_name
379
# SERVER_SOFTWARE is actually not Apache but IVLE, since we are
380
# custom-making the CGI request.
381
env['SERVER_SOFTWARE'] = "IVLE/" + str(conf.ivle_version)