[web2py] Re: id field is editable through REST PUT request

2014-04-16 Thread Derek
You're right, I guess you should store the ID in session state... but wait, 
this is ReST... part of the url then, and not a parameter. and PUT should 
not take the record_id.

On Saturday, April 12, 2014 3:01:20 PM UTC-7, Massimo Di Pierro wrote:

 That is not a hole.

 This code:


 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 means:

 allow anybody to put any content in any record of any table. If that is 
 not what you want you should write different code.

 On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:

 That seems like a pretty big hole then especially if IDs are used as 
 foreign keys... ownership doesn't mean anything. I could write an 
 inflammatory comment on a website, change the owner to someone else (via 
 the edit form) and then suddenly that other user is banned...

 On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can specify 
 a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 So, for example, on a db with db.person.id.writable = False, a 
 request to http://127.0.0.1:8000/appname/default/api/person/1?id=100; 
 will modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be 
 clever enough to play around with our UI and figure out the REST calls 
 being made, he/she could potentially mess with all the ids and 
 relationships of the resources, at least for that particular account (and 
 any other resources we've exposed).

 Am I missing something? Does db.person.id.writable = False only apply 
 to SQLFORMs? Is there some other way to prevent modification of the id 
 field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-16 Thread Henry Nguyen
Simply inserting into the tables blindly was the problem, as Massimo 
pointed out. I've gone ahead and implemented manual checking of the vars:

def PUT(*args, **vars):

required_vars = ['id']
optional_vars = ['first_name','last_name']

# Check for required vars
for var in required_vars:
if var not in vars.keys():
raise HTTP(400, 'Missing:  ' + var)

# Check that vars are only allowed vars
for key in vars.keys():
if key not in required_vars and key not in optional_vars:
raise HTTP(400, 'Invalid: ' + key)

result = db(
(db.person.id == vars.get('id')) 
(db.person.auth_user_id == auth.user.id)
).validate_and_update(**vars)

return dict(result=result)

I was hoping there'd be an easier way to specify validation constraints for 
the REST calls, similar to db.table.field.writable = False. Unfortunately, 
this only applies to the built-in SQLFORMs.

Henry

On Wednesday, April 16, 2014 11:06:42 AM UTC-7, Derek wrote:

 You're right, I guess you should store the ID in session state... but 
 wait, this is ReST... part of the url then, and not a parameter. and PUT 
 should not take the record_id.

 On Saturday, April 12, 2014 3:01:20 PM UTC-7, Massimo Di Pierro wrote:

 That is not a hole.

 This code:


 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 means:

 allow anybody to put any content in any record of any table. If that is 
 not what you want you should write different code.

 On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:

 That seems like a pretty big hole then especially if IDs are used as 
 foreign keys... ownership doesn't mean anything. I could write an 
 inflammatory comment on a website, change the owner to someone else (via 
 the edit form) and then suddenly that other user is banned...

 On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can specify 
 a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update
 (**vars)

 So, for example, on a db with db.person.id.writable = False, a 
 request to http://127.0.0.1:8000/appname/default/api/person/1?id=100; 
 will modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be 
 clever enough to play around with our UI and figure out the REST calls 
 being made, he/she could potentially mess with all the ids and 
 relationships of the resources, at least for that particular account (and 
 any other resources we've exposed).

 Am I missing something? Does db.person.id.writable = False only 
 apply to SQLFORMs? Is there some other way to prevent modification of the 
 id field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-16 Thread Niphlod
it's not that far-fetch to include a control for writable = False 
fields.

def PUT(table_name, record_id, **vars):
tb = db[table_name]
cant_update_those = [tb[k] for k in tb.fields if tb[k].writable is 
False]
invalid_fields = set(vars)  set(cant_update_those)
if invalid_fields:
raise HTTP(400, 'whatever')
return db(tb._id==record_id).validate_and_update(**vars)

ask for more details if needed.

On Wednesday, April 16, 2014 8:15:42 PM UTC+2, Henry Nguyen wrote:

 Simply inserting into the tables blindly was the problem, as Massimo 
 pointed out. I've gone ahead and implemented manual checking of the vars:

 def PUT(*args, **vars):

 required_vars = ['id']
 optional_vars = ['first_name','last_name']
 
 # Check for required vars
 for var in required_vars:
 if var not in vars.keys():
 raise HTTP(400, 'Missing:  ' + var)

 # Check that vars are only allowed vars
 for key in vars.keys():
 if key not in required_vars and key not in optional_vars:
 raise HTTP(400, 'Invalid: ' + key)

 result = db(
 (db.person.id == vars.get('id')) 
 (db.person.auth_user_id == auth.user.id)
 ).validate_and_update(**vars)

 return dict(result=result)

 I was hoping there'd be an easier way to specify validation constraints 
 for the REST calls, similar to db.table.field.writable = False. 
 Unfortunately, this only applies to the built-in SQLFORMs.

 Henry

 On Wednesday, April 16, 2014 11:06:42 AM UTC-7, Derek wrote:

 You're right, I guess you should store the ID in session state... but 
 wait, this is ReST... part of the url then, and not a parameter. and PUT 
 should not take the record_id.

 On Saturday, April 12, 2014 3:01:20 PM UTC-7, Massimo Di Pierro wrote:

 That is not a hole.

 This code:


 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 means:

 allow anybody to put any content in any record of any table. If that 
 is not what you want you should write different code.

 On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:

 That seems like a pretty big hole then especially if IDs are used as 
 foreign keys... ownership doesn't mean anything. I could write an 
 inflammatory comment on a website, change the owner to someone else (via 
 the edit form) and then suddenly that other user is banned...

 On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can 
 specify a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update
 (**vars)

 So, for example, on a db with db.person.id.writable = False, a 
 request to http://127.0.0.1:8000/appname/default/api/person/1?id=100; 
 will modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be 
 clever enough to play around with our UI and figure out the REST calls 
 being made, he/she could potentially mess with all the ids and 
 relationships of the resources, at least for that particular account 
 (and 
 any other resources we've exposed).

 Am I missing something? Does db.person.id.writable = False only 
 apply to SQLFORMs? Is there some other way to prevent modification of 
 the 
 id field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-16 Thread Henry Nguyen
Nice... thank you, Niphlod... I hadn't even considered checking that field 
attribute directly like that. 

Henry

On Wednesday, April 16, 2014 1:14:21 PM UTC-7, Niphlod wrote:

 it's not that far-fetch to include a control for writable = False 
 fields.

 def PUT(table_name, record_id, **vars):
 tb = db[table_name]
 cant_update_those = [tb[k] for k in tb.fields if tb[k].writable is 
 False]
 invalid_fields = set(vars)  set(cant_update_those)
 if invalid_fields:
 raise HTTP(400, 'whatever')
 return db(tb._id==record_id).validate_and_update(**vars)

 ask for more details if needed.

 On Wednesday, April 16, 2014 8:15:42 PM UTC+2, Henry Nguyen wrote:

 Simply inserting into the tables blindly was the problem, as Massimo 
 pointed out. I've gone ahead and implemented manual checking of the vars:

 def PUT(*args, **vars):

 required_vars = ['id']
 optional_vars = ['first_name','last_name']
 
 # Check for required vars
 for var in required_vars:
 if var not in vars.keys():
 raise HTTP(400, 'Missing:  ' + var)

 # Check that vars are only allowed vars
 for key in vars.keys():
 if key not in required_vars and key not in optional_vars:
 raise HTTP(400, 'Invalid: ' + key)

 result = db(
 (db.person.id == vars.get('id')) 
 (db.person.auth_user_id == auth.user.id)
 ).validate_and_update(**vars)

 return dict(result=result)

 I was hoping there'd be an easier way to specify validation constraints 
 for the REST calls, similar to db.table.field.writable = False. 
 Unfortunately, this only applies to the built-in SQLFORMs.

 Henry

 On Wednesday, April 16, 2014 11:06:42 AM UTC-7, Derek wrote:

 You're right, I guess you should store the ID in session state... but 
 wait, this is ReST... part of the url then, and not a parameter. and PUT 
 should not take the record_id.

 On Saturday, April 12, 2014 3:01:20 PM UTC-7, Massimo Di Pierro wrote:

 That is not a hole.

 This code:


 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 means:

 allow anybody to put any content in any record of any table. If that 
 is not what you want you should write different code.

 On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:

 That seems like a pretty big hole then especially if IDs are used as 
 foreign keys... ownership doesn't mean anything. I could write an 
 inflammatory comment on a website, change the owner to someone else (via 
 the edit form) and then suddenly that other user is banned...

 On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify 
 REST endpoints for our resources. During testing, I noticed that I can 
 specify a PUT request var of id=x where x is some new id and the id 
 of 
 that row will change to x. This is even WITH db.table.id.writable = 
 False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update
 (**vars)

 So, for example, on a db with db.person.id.writable = False, a 
 request to 
 http://127.0.0.1:8000/appname/default/api/person/1?id=100; will 
 modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be 
 clever enough to play around with our UI and figure out the REST calls 
 being made, he/she could potentially mess with all the ids and 
 relationships of the resources, at least for that particular account 
 (and 
 any other resources we've exposed).

 Am I missing something? Does db.person.id.writable = False only 
 apply to SQLFORMs? Is there some other way to prevent modification of 
 the 
 id field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-12 Thread Massimo Di Pierro
That is not a hole.

This code:


def PUT(table_name, record_id, **vars):
return db(db[table_name]._id==record_id).validate_and_update(**vars)

means:

allow anybody to put any content in any record of any table. If that is 
not what you want you should write different code.

On Friday, 11 April 2014 12:36:43 UTC-5, Derek wrote:

 That seems like a pretty big hole then especially if IDs are used as 
 foreign keys... ownership doesn't mean anything. I could write an 
 inflammatory comment on a website, change the owner to someone else (via 
 the edit form) and then suddenly that other user is banned...

 On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can specify a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 So, for example, on a db with db.person.id.writable = False, a 
 request to http://127.0.0.1:8000/appname/default/api/person/1?id=100; 
 will modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be 
 clever enough to play around with our UI and figure out the REST calls 
 being made, he/she could potentially mess with all the ids and 
 relationships of the resources, at least for that particular account (and 
 any other resources we've exposed).

 Am I missing something? Does db.person.id.writable = False only apply 
 to SQLFORMs? Is there some other way to prevent modification of the id 
 field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-11 Thread Derek
That seems like a pretty big hole then especially if IDs are used as 
foreign keys... ownership doesn't mean anything. I could write an 
inflammatory comment on a website, change the owner to someone else (via 
the edit form) and then suddenly that other user is banned...

On Wednesday, April 9, 2014 2:03:53 PM UTC-7, Massimo Di Pierro wrote:

  Does db.person.id.writable = False only apply to SQLFORMs?

 yes. 

 On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can specify a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 So, for example, on a db with db.person.id.writable = False, a request 
 to http://127.0.0.1:8000/appname/default/api/person/1?id=100; will 
 modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be clever 
 enough to play around with our UI and figure out the REST calls being made, 
 he/she could potentially mess with all the ids and relationships of the 
 resources, at least for that particular account (and any other resources 
 we've exposed).

 Am I missing something? Does db.person.id.writable = False only apply 
 to SQLFORMs? Is there some other way to prevent modification of the id 
 field?

 Thanks ahead of time for any help.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: id field is editable through REST PUT request

2014-04-09 Thread Massimo Di Pierro
 Does db.person.id.writable = False only apply to SQLFORMs?

yes. 

On Tuesday, 8 April 2014 18:31:54 UTC-5, Henry Nguyen wrote:

 Our product is using the @request.restful() decorator to specify REST 
 endpoints for our resources. During testing, I noticed that I can specify a 
 PUT request var of id=x where x is some new id and the id of that row 
 will change to x. This is even WITH db.table.id.writable = False. 

 The PUT method is defined as follows:

 def PUT(table_name, record_id, **vars):
 return db(db[table_name]._id==record_id).validate_and_update(**
 vars)

 So, for example, on a db with db.person.id.writable = False, a request 
 to http://127.0.0.1:8000/appname/default/api/person/1?id=100; will 
 modify the person row with id 1 to be id 100.

 This seems like a relatively major problem... if a user were to be clever 
 enough to play around with our UI and figure out the REST calls being made, 
 he/she could potentially mess with all the ids and relationships of the 
 resources, at least for that particular account (and any other resources 
 we've exposed).

 Am I missing something? Does db.person.id.writable = False only apply to 
 SQLFORMs? Is there some other way to prevent modification of the id field?

 Thanks ahead of time for any help.


-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.