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 [email protected].
For more options, visit https://groups.google.com/d/optout.