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?
>>>>>>>>  -- 
>>>>>>>>  
>>>>>>>>  
>>>>>>>>  
>>>>>>>>
>>>>>>>  
>>>>>>>
>>>>>>>  -- 
>>>>>>>  
>>>>>>>  
>>>>>>>  
>>>>>>>
>>>>>>>
>>>>>>>        -- 
>>  
>>  
>>  
>>
>>
>>  

-- 



Reply via email to