I should add that if user_signature=False the tables are always exposed in readonly mode: SQLFORM.grid(..,editable=False, create=False, deletable=False)
On Friday, 7 September 2012 14:50:56 UTC-5, Massimo Di Pierro wrote: > > I only talk for 2.0.x. > > Yes. That is prevented with the default user_signature=True. > > If you disable user signature with user_signature=False than you expose > yourself to major security risks and may expose the entire database. > user_signature = False should only be used for testing or if you manually > disable edit access. For example: > > grid = SQLFORM.grid(..,editable=False, create=False, deletable=False). > > > On Friday, 7 September 2012 14:43:22 UTC-5, Kevin C wrote: >> >> I guess I need to look into the auth.signature functionality. We >> already had our grid conditional be db.pages.stores_id=STORE_INFO.id but we >> were able to edit Store 1's page while logged into Store 2's administration >> area, just by changing the ID in the URL. Are you saying that >> auth.signature will prevent this? >> >> Kevin Cackler >> Tech Daddies >> 501-205-1512http://www.techdaddies.com >> >> On 9/7/2012 2:39 PM, Massimo Di Pierro wrote: >> >> In some sense the grid does what you say. >> >> For example: >> >> @auth.requires_login() >> def index(): >> db.define_table('thing',Field('name'),auth.signature) >> grid = SQLFORM.grid(db.thing.created_by==auth.user_id) >> return locals() >> >> Notice all the URLs linked by the grid are digitally signed. They are >> one time URLs. They can only be used by the user within this session and >> they cannot be tampered with. For example replacing the id of a record with >> another record in the edit page will not give access to the other record >> because would break the signature. This was broken in 1.99.7 for the grid >> (and in fact it was experimental) but it is fixed in 2.0.x. >> >> Users can digitally sign any URL: >> >> def index(): >> ... >> link = URL('edit',args=id,user_signature=True) >> return dict(link=link) >> >> @auth.requires_signature() >> def edit(): >> ... >> >> Now the http://.../edit/<id>?signature=<signature> is still the id of >> the record but without the signature the URL is not valid. >> >> >> >> >> >> On Friday, 7 September 2012 13:27:49 UTC-5, MichaelF wrote: >>> >>> Thanks, Massimo. >>> >>> Re. needing a way to reference individual records: of course. But it >>> doesn't have to be the internal record id (primary key value). The php code >>> we used gave out unique-per-request values so that one couldn't, say, use a >>> key retrieved from one form in another form. >>> >>> The @auth infrastructure is great. It's not a record-level design (or >>> is it?). I just hate to think that internal db keys are public info. Okay, >>> perhaps I'm going over the edge being worried about exposing database >>> primary keys. But I find that when I decide I'm going over the edge, that >>> means that some cracker will find a way to use that information against my >>> site. >>> >>> I don't think web2py is much different from other infrastructures on >>> this issue. I wanted to know what others thought; thanks for your reply. >>> >>> Michael >>> >>> On Friday, September 7, 2012 10:28:08 AM UTC-6, Massimo Di Pierro wrote: >>>> >>>> I strongly disagree with this. >>>> >>>> Publishing record IDs does not imply indirect object reference >>>> vulnerability. Any application that publishes record information must >>>> have a way to reference individual records. If the individual access >>>> is not validated than the app is vulnerable to indirect object reference, >>>> whether or not the reference is done by id or not. >>>> >>>> Who can access what is a matter of policy and policy must be >>>> implemented by the developer. Web2py provides the >>>> @auth.requires_permission >>>> and @auth.requires_membership and $auth.requires_signature. >>>> >>>> Massimo >>>> >>>> On Friday, 7 September 2012 09:22:12 UTC-5, MichaelF wrote: >>>>> >>>>> I appreciate that web2py has ways to handle this, and I also agree >>>>> that it's somewhat hackish. The problem remains, though, that we're still >>>>> exposing (publishing) internal primary keys to the browser. Isn't the >>>>> main >>>>> problem the fact that we're dealing with primary key values being sent to >>>>> the browser? Look at https://www.owasp.org/index.php/Top_10_2010-A4 for >>>>> one description of the vulnerability. >>>>> >>>>> In our php application we wrote a class that hashed primary keys >>>>> sent to the browser, giving different hashes on each GET/POST so that, >>>>> for >>>>> example, the hashed primary key 1 would different if the user visited the >>>>> same page two times. >>>>> >>>>> Thoughts? >>>>> >>>>> Thanks. >>>>> >>>>> On Thursday, September 6, 2012 8:18:44 AM UTC-6, Anthony wrote: >>>>>> >>>>>> How about >>>>>> http://web2py.com/books/default/chapter/29/06#Common-filters or >>>>>> http://web2py.com/books/default/chapter/29/06#Common-fields-and-multi-tenancy? >>>>>> >>>>>> >>>>>> >>>>>> Anthony >>>>>> >>>>>> On Wednesday, September 5, 2012 8:48:49 PM UTC-4, Kevin C wrote: >>>>>>> >>>>>>> We did something similar but it feels very hackish, considering it >>>>>>> has to be done in every method of the admin controller. I just wanted >>>>>>> to >>>>>>> see if there was a better way. >>>>>>> >>>>>>> Thank you. >>>>>>> >>>>>>> Kevin Cackler >>>>>>> Tech Daddies >>>>>>> 501-205-1512http://www.techdaddies.com >>>>>>> >>>>>>> On 9/5/2012 7:45 PM, Bruno Rocha wrote: >>>>>>> >>>>>>> You can do: >>>>>>> >>>>>>> if request.args(0) in ['edit', 'delete']: >>>>>>> STORE_DETAILS.id == int(request.args(2)) or >>>>>>> redirect(URL('default', 'wherever')) >>>>>>> >>>>>>> db.pages.stores_id.default = STORE_DETAILS.id >>>>>>> query = ((db.pages.stores_id == STORE_DETAILS.id)) >>>>>>> form = SQLFORM.grid(query=query) >>>>>>> >>>>>>> return dict(form=form) >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wed, Sep 5, 2012 at 9:38 PM, Kevin C <[email protected]>wrote: >>>>>>> >>>>>>>> Basically, we are generating a SQLFORM.grid with the following >>>>>>>> code: >>>>>>>> >>>>>>>> db.pages.stores_id.default = STORE_DETAILS.id >>>>>>>> query = ((db.pages.stores_id == STORE_DETAILS.id)) >>>>>>>> form = SQLFORM.grid(query=query) >>>>>>>> >>>>>>>> return dict(form=form) >>>>>>>> >>>>>>>> This is working perfectly fine for us. However, we have noticed >>>>>>>> that if we just change the ID in the query string for the edit page, >>>>>>>> we are >>>>>>>> allowed to edit other store's entries. >>>>>>>> >>>>>>>> IE >>>>>>>> http://test.oursite.com/test/admin/pages/edit/pages/6?_signature=f8c5560743.<http://test.shofty.com/shofty/admin/pages/edit/pages/6?_signature=f8c55607435864253b5f5b37a6b7109956e4a8fa> >>>>>>>> .. >>>>>>>> >>>>>>>> What is the proper way to do this, then? The grid itself looks >>>>>>>> great, but just by changing the page ID in the URL, we are allowed to >>>>>>>> edit >>>>>>>> pages not belonging to us. I guess I was hoping that the query >>>>>>>> conditional >>>>>>>> would be passed to each function (add, edit, delete) but that >>>>>>>> obviously is >>>>>>>> not the case. Is multi-tenancy the solution to this issue or are we >>>>>>>> overlooking something simple? >>>>>>>> -- >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >> >> >> >> >> >> --

