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-1512
http://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
<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
<http://web2py.com/books/default/chapter/29/06#Common-filters>
or
http://web2py.com/books/default/chapter/29/06#Common-fields-and-multi-tenancy
<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-1512
http://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?
--
--
--
--