fixed security issue in grid

This commit is contained in:
mdipierro
2012-08-16 10:54:38 -05:00
parent d2bbc9adaf
commit d05eb2aa6e
2 changed files with 61 additions and 83 deletions

View File

@@ -1 +1 @@
Version 2.00.0 (2012-08-16 09:39:49) dev
Version 2.00.0 (2012-08-16 10:54:35) dev

View File

@@ -1616,9 +1616,27 @@ class SQLFORM(FORM):
def url(**b):
b['args'] = args+b.get('args',[])
b['hash_vars']=False
b['user_signature'] = user_signature
return URL(**b)
def url2(**b):
b['args'] = request.args+b.get('args',[])
b['hash_vars']=False
b['user_signature'] = user_signature
return URL(**b)
referrer = session.get('_web2py_grid_referrer_'+formname, url())
if user_signature:
if (args != request.args and \
not URL.verify(request,user_signature=user_signature)) or \
(not auth.user and \
('edit' in request.args or \
'create' in request.args or \
'delete' in request.args)):
session.flash = T('not authorized')
redirect(referrer)
def gridbutton(buttonclass='buttonadd',buttontext='Add',
buttonurl=url(args=[]),callback=None,delete=None,trap=True):
if showbuttontext:
@@ -1660,16 +1678,9 @@ class SQLFORM(FORM):
fields.append(field_id)
table = field_id.table
tablename = table._tablename
referrer = session.get('_web2py_grid_referrer_'+formname, url())
def check_authorization():
if user_signature:
if not URL.verify(request,user_signature=user_signature):
session.flash = T('not authorized')
redirect(referrer)
if upload=='<default>':
upload = lambda filename: url(args=['download',filename])
if len(request.args)>1 and request.args[-2]=='download':
check_authorization()
stream = response.download(request,db)
raise HTTP(200,stream,**response.headers)
@@ -1699,7 +1710,6 @@ class SQLFORM(FORM):
sqlformargs = dict(formargs)
if create and len(request.args)>1 and request.args[-2] == 'new':
check_authorization()
table = db[request.args[-1]]
sqlformargs.update(createargs)
create_form = SQLFORM(
@@ -1716,8 +1726,8 @@ class SQLFORM(FORM):
res.view_form = view_form
res.search_form = search_form
return res
elif details and len(request.args)>2 and request.args[-3]=='view':
check_authorization()
table = db[request.args[-2]]
record = table(request.args[-1]) or redirect(URL('error'))
sqlformargs.update(viewargs)
@@ -1732,7 +1742,6 @@ class SQLFORM(FORM):
res.search_form = search_form
return res
elif editable and len(request.args)>2 and request.args[-3]=='edit':
check_authorization()
table = db[request.args[-2]]
record = table(request.args[-1]) or redirect(URL('error'))
sqlformargs.update(editargs)
@@ -1754,42 +1763,24 @@ class SQLFORM(FORM):
res.search_form = search_form
return res
elif deletable and len(request.args)>2 and request.args[-3]=='delete':
check_authorization()
table = db[request.args[-2]]
if ondelete:
ondelete(table,request.args[-1])
ret = db(table[table._id.name]==request.args[-1]).delete()
return ret
#elif csv and len(request.args)>0 and request.args[-1]=='csv':
# if request.vars.keywords:
# try:
# dbset=dbset(SQLFORM.build_query(
# fields,
# request.vars.get('keywords','')))
# except:
# raise HTTP(400)
# check_authorization()
# response.headers['Content-Type'] = 'text/csv'
# response.headers['Content-Disposition'] = \
# 'attachment;filename=rows.csv;'
# raise HTTP(200,str(dbset.select()),
# **{'Content-Type':'text/csv',
# 'Content-Disposition':'attachment;filename=rows.csv;'})
#==============================================================================
exportManager = dict(csv_with_hidden_cols=(ExporterCsv,'csv, hidden cols'),
csv=ExporterCsv,
html=ExporterHtml,
tsv_with_hidden_cols=(ExporterTsv, 'tsv (Excel compatible), hidden cols'),
tsv=(ExporterTsv, 'tsv (Excel compatible)')
)
exportManager = dict(
csv_with_hidden_cols=(ExporterCsv,'csv, hidden cols'),
csv=ExporterCsv,
html=ExporterHtml,
tsv_with_hidden_cols=(ExporterTsv,
'tsv (Excel compatible), hidden cols'),
tsv=(ExporterTsv, 'tsv (Excel compatible)'))
if not exportclasses is None:
exportManager.update(exportclasses)
if len(request.args)>0 and request.args[-1]=='export':
export_type = request.vars.export_type
export_type = request.vars._export_type
if export_type:
order = request.vars.order or ''
if sortable:
if order and not order=='None':
@@ -1807,21 +1798,17 @@ class SQLFORM(FORM):
if export_type in ('csv_with_hidden_cols','tsv_with_hidden_cols'):
if request.vars.keywords:
try:
dbset=dbset(SQLFORM.build_query(
fields,
request.vars.get('keywords','')))
except:
raise HTTP(400)
rows = dbset.select()
dbset = dbset(SQLFORM.build_query(
fields,request.vars.get('keywords','')))
rows = dbset.select()
except Exception, e:
response.flash = T('Internal Error')
rows = []
else:
rows = dbset.select()
else:
rows = dbset.select(left=left,orderby=orderby,*columns)
##FIXME ?
#check_authorization()
if user_signature:
if not URL.verify(request,user_signature=user_signature,
hash_vars=False):
session.flash = T('not authorized')
redirect(referrer)
if not export_type is None:
if exportManager.has_key(export_type):
value = exportManager[export_type]
@@ -1833,12 +1820,11 @@ class SQLFORM(FORM):
filename = '.'.join(('rows', oExp.file_ext))
response.headers['Content-Type'] = oExp.content_type
response.headers['Content-Disposition'] = \
'attachment;filename='+filename+';'
'attachment;filename='+filename+';'
raise HTTP(200, oExp.export(),
**{'Content-Type':oExp.content_type,
'Content-Disposition':'attachment;filename='+filename+';'})
#================================================================================
elif request.vars.records and not isinstance(
request.vars.records,list):
@@ -1846,9 +1832,7 @@ class SQLFORM(FORM):
elif not request.vars.records:
request.vars.records=[]
session['_web2py_grid_referrer_'+formname] = \
URL(args=request.args,vars=request.vars,
user_signature=user_signature)
session['_web2py_grid_referrer_'+formname] = url2(vars=request.vars)
console = DIV(_class='web2py_console %(header)s %(cornertop)s' % ui)
error = None
if searchable:
@@ -1898,14 +1882,6 @@ class SQLFORM(FORM):
buttontext='Add',
buttonurl=url(args=['new',tablename])))
if csv and nrows:
#search_actions.append(gridbutton(
# buttonclass='buttonexport',
# buttontext='Export',
# trap = False,
# buttonurl=url(args=['csv'],
# vars=dict(keywords=request.vars.keywords or ''))))
#================================================================
options =[]
for k,v in sorted(exportManager.items()):
if hasattr(v, "__getitem__"):
@@ -1913,23 +1889,24 @@ class SQLFORM(FORM):
else:
label = k
options.append(OPTION(T(label),_value=k))
##FIXME ?
mysignature = url(args=['export']).split('?', 1)
mysignature = psq(mysignature[-1]).get('_signature', [None])[-1]
items = url2().split('?', 1)
myurl = items[0]
if len(items)>1:
mysignature = psq(items[1]).get('_signature', [None])[-1]
else:
mysignature = ''
f = FORM(BUTTON(SPAN(_class=ui.get('buttonexport')),
"Export", _type="submit", _class=ui.get('button')),
SELECT(options, _name="export_type"),
SELECT(options, _name="_export_type"),
INPUT(_type="hidden", _name="order",
_value=request.vars.order),
INPUT(_type="hidden", _name="_signature",
_value=mysignature),
INPUT(_type="hidden", _name="keywords",
_value=request.vars.keywords or ''),
_method="GET", _action=url(args=['export']))
_method="GET", _action=myurl)
search_actions.append(f)
#================================================================
console.append(search_actions)
order = request.vars.order or ''
@@ -2153,6 +2130,13 @@ class SQLFORM(FORM):
"""
request, T = current.request, current.T
if args is None: args = []
def url(**b):
b['args'] = request.args[:nargs]+b.get('args',[])
b['hash_vars']=False
b['user_signature'] = user_signature
return URL(**b)
db = table._db
breadcrumbs = []
if request.args(len(args)) != table._tablename:
@@ -2195,15 +2179,12 @@ class SQLFORM(FORM):
breadcrumbs.append(
LI(A(T(db[referee]._plural),
_class=trap_class(),
_href=URL(args=request.args[:nargs],
user_signature=user_signature)),
_href=url()),
SPAN(divider,_class='divider')))
if kwargs.get('details',True):
breadcrumbs.append(
LI(A(name,_class=trap_class(),
_href=URL(args=request.args[:nargs]+[
'view',referee,id],
user_signature=user_signature)),
_href=url(args=['view',referee,id])),
SPAN(divider,_class='divider')))
nargs+=2
else:
@@ -2211,7 +2192,7 @@ class SQLFORM(FORM):
if nargs>len(args)+1:
query = (field == id)
if linked_tables is None or referee in linked_tables:
field.represent = lambda id,r=None,referee=referee,rep=field.represent: A(callable(rep) and rep(id) or id,_class=trap_class(),_href=URL(args=request.args[:nargs]+['view',referee,id], user_signature=user_signature))
field.represent = lambda id,r=None,referee=referee,rep=field.represent: A(callable(rep) and rep(id) or id,_class=trap_class(),_href=url(args=['view',referee,id]))
except (KeyError,ValueError,TypeError):
redirect(URL(args=table._tablename))
if nargs==len(args)+1:
@@ -2243,9 +2224,8 @@ class SQLFORM(FORM):
args0 = tablename+'.'+fieldname
links.append(
lambda row,t=t,nargs=nargs,args0=args0:\
A(SPAN(t),_class=trap_class(),_href=URL(
args=request.args[:nargs]+[args0,row[id_field_name]],
user_signature=user_signature)))
A(SPAN(t),_class=trap_class(),_href=url(
args=[args0,row[id_field_name]])))
grid=SQLFORM.grid(query,args=request.args[:nargs],links=links,
links_in_grid=links_in_grid,
@@ -2253,9 +2233,7 @@ class SQLFORM(FORM):
if isinstance(grid,DIV):
header = table._plural + (field and ' for '+field.name or '')
breadcrumbs.append(LI(A(T(header),_class=trap_class(),
_href=URL(args=request.args[:nargs],
user_signature=user_signature)),
_class='active'))
_href=url()),_class='active'))
grid.insert(0,DIV(UL(*breadcrumbs, **{'_class':breadcrumbs_class}),
_class='web2py_breadcrumbs'))
return grid