smartgrid tampering with url in browser

100 views
Skip to first unread message

T.R.Rajkumar

unread,
Jun 20, 2017, 6:42:11 AM6/20/17
to web2py-users
I have this page from the edit button of the child.
http://127.0.0.1:8000/web_ocms/amc/new_contract/amc_master/amc_details.amc_id/17/edit/amc_details/10
Here 17 is the id of the master and 10 is the id of the child.
I have set common_filter in controller so that the records of master and child belonging to the logged in user is listed in grid.
So in controller I check the master id and child id and if not of the user I raise a flash tampering not allowed and redirect to the master grid.
So far OK.
But now if 17 and 10 are tampered to say 20 and 25 and the new record also belongs to the user the form show the record to edit.
I would like that the tampering of url not be allowed. That is if one clicks the edit button and gets the above url I should allow processing only with 17 and 10 and not any other record.
Thanks for suggestions.

Anthony

unread,
Jun 20, 2017, 1:08:07 PM6/20/17
to web2py-users
Have you tried user_signature=True?

T.R.Rajkumar

unread,
Jun 21, 2017, 3:05:38 AM6/21/17
to web2py-users
Yes, Anthony now with user_signature = True prevents tampering of urls generated by smartgrid.
This is when I use auth and signup and then call the grid.
But in my app I am using custom login form with user credentials from a legacy table.
Can I achieve the same result with custom login form?
As of now in login form I set session.logged_id = True if credentials are OK.
In db.py I have this function.

def check_logged_in(callee):
    def wrapper():
        if session.logged_in == None:
            session.flash = 'Please login.'
            redirect(URL('login', 'login'))
        else:
            return callee()
    return wrapper

and in controller I do this
@check_logged_in
def new_contract():

With this set up if I set user_signature = True in grid it does not allow editing and inserting. It allows only viewing.
How to achieve the same effect as auth using my check_logged_in function.
Thank you for the help.
Regards.
 

Anthony

unread,
Jun 21, 2017, 3:46:37 PM6/21/17
to web2py-users
The user_signature functionality expects auth.hmac_key in the session, so, you could add something like the following in a model file:

from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session
.auth = Storage(hmac_key=web2py_uuid())

Anthony

T.R.Rajkumar

unread,
Jun 22, 2017, 1:06:05 AM6/22/17
to web2py-users
I put the below  code in my model file amc.py


from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session.auth = Storage(hmac_key=web2py_uuid())

But now when in run http://127.0.0.1:8000/web_ocms/amc/new_contract I get this error.

Error ticket for "web_ocms"

Ticket ID

127.0.0.1.2017-06-22.10-26-57.a604f48d-7432-4cf3-b628-81168a796052

<type 'exceptions.TypeError'> unsupported type for timedelta seconds component: NoneType

Version

web2py™ Version 2.14.6-stable+timestamp.2016.05.10.00.21.47
Python Python 2.7.5: D:\Python\python.exe (prefix: D:\Python)

Traceback

1.
2.
3.
4.
5.
6.
7.
8.
9.
Traceback (most recent call last):
File "D:\web2py\gluon\restricted.py", line 227, in restricted
exec ccode in environment
File "D:/web2py/applications/web_ocms/models/db.py", line 86, in <module>
auth = Auth(db, host_names=myconf.get('host.names'))
File "D:\web2py\gluon\tools.py", line 1766, in __init__
delta = datetime.timedelta(days=0, seconds=auth.expiration)
TypeError: unsupported type for timedelta seconds component: NoneType

Error snapshot help

<type 'exceptions.TypeError'>(unsupported type for timedelta seconds component: NoneType)

inspect attributes

Frames

  • File D:\web2py\gluon\restricted.py in restricted at line 227 code arguments variables

  • File D:\web2py\applications\web_ocms\models\db.py in <module> at line 86 code arguments variables

  • File D:\web2py\gluon\tools.py in __init__ at line 1766 code arguments variables

    Function argument list

    (self=<gluon.tools.Auth object>, environment=<DAL uri="mssql2:******@172.16.164.64\SQLEXPRESS/ocms_nlc">, db=<DAL uri="mssql2:******@172.16.164.64\SQLEXPRESS/ocms_nlc">, mailer=True, hmac_key=None, controller='default', function='user', cas_provider=None, signature=True, secure=False, csrf_prevention=True, propagate_extension=None, url_index=None, jwt=None, host_names=['localhost:*', '127.0.0.1:*', '*:*', '*'])

    Code listing
    1761.
    1762.
    1763.
    1764.
    1765.
    1766.

    1767.
    1768.
    1769.
    1770.
            # if we have auth info
    # if not expired it, used it
    # if expired, clear the session
    # else, only clear auth info in the session
    if auth:
    delta = datetime.timedelta(days=0, seconds=auth.expiration)

    if auth.last_visit and auth.last_visit + delta > now:
    self.user = auth.user
    # this is a trick to speed up sessions to avoid many writes
    if (now - auth.last_visit).seconds > (auth.expiration / 10):
    Variables
    auth.expiration None
    seconds undefined
    days undefined
    auth <Storage {'hmac_key': '58fb6e67-49ea-4063-986d-8406469f6309'}>
    global datetime <module 'datetime' (built-in)>
    delta undefined
    datetime.timedelta <type 'datetime.timedelta'>
So now I commented in db.py
#auth = Auth(db, host_names=myconf.get('host.names'))

After commenting auth the url works. Is this because of the hmac_key ?


Dave S

unread,
Jun 22, 2017, 2:32:47 AM6/22/17
to web2py-users


On Wednesday, June 21, 2017 at 10:06:05 PM UTC-7, T.R.Rajkumar wrote:
I put the below  code in my model file amc.py

from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session.auth = Storage(hmac_key=web2py_uuid())

But now when in run http://127.0.0.1:8000/web_ocms/amc/new_contract I get this error.

Error ticket for "web_ocms"

Ticket ID

127.0.0.1.2017-06-22.10-26-57.a604f48d-7432-4cf3-b628-81168a796052

<type 'exceptions.TypeError'> unsupported type for timedelta seconds component: NoneType

[...]
 
# else, only clear auth info in the session

  •         if auth:
    delta = datetime.timedelta(days=0, seconds=auth.expiration)

    if auth.last_visit and auth.last_visit + delta > now:
    self.user = auth.user
    # this is a trick to speed up sessions to avoid many writes
    if (now - auth.last_visit).seconds > (auth.expiration / 10):
  • Variables
    auth.expiration None
    [...]


    auth <Storage {'hmac_key': '58fb6e67-49ea-4063-986d-8406469f6309'}>
    [...]




So now I commented in db.py
#auth = Auth(db, host_names=myconf.get('host.names'))

After commenting auth the url works. Is this because of the hmac_key ?




It looks like you're confusing the initialization by setting  auth data in the session without including fields it expects.  If you're in a new session, web2py won't have set auth data yet, but it still checks to see if the session includes old auth data.  Perhaps you could set auth.expiration=somenumseconds when you set the hmac_key.

Caveat: I haven't checked to see if there are other auth fields that might trip you up in a similar way
.  It looks like an hmac_key is normally set by the _init routine after this expiration check.

/dps

T.R.Rajkumar

unread,
Jun 22, 2017, 6:11:46 AM6/22/17
to web2py-users
If I am not defining auth the error does not appear, but the grid user_signature is not working. I am setting the hmac_key as mentioned in model amc.py.

from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session.auth = Storage(hmac_key=web2py_uuid()

How can I make grid user_signature to work without auth.

Anthony

unread,
Jun 22, 2017, 10:23:54 AM6/22/17
to web2py-users
As far as I understand, you are not using Auth, so why are you defining auth = Auth(...) at all? Just get rid of that line.

T.R.Rajkumar

unread,
Jun 23, 2017, 1:35:23 AM6/23/17
to web2py-users
Anthony, When I comment out auth and in model amc/amc.py I add this

from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session.auth = Storage(hmac_key=web2py_uuid())

Now the smartgrid lists the rows but when add or edit button is clicked I get not authorized flash message and it is not allowing to edit or add records. Also when I place the mouse over edit button I see the edit urls are not digitally signed.

Anthony

unread,
Jun 23, 2017, 4:41:46 PM6/23/17
to web2py-users
On Friday, June 23, 2017 at 1:35:23 AM UTC-4, T.R.Rajkumar wrote:
Anthony, When I comment out auth and in model amc/amc.py I add this
from gluon.storage import Storage
from gluon.utils import web2py_uuid
if not 'auth' in session:
    session.auth = Storage(hmac_key=web2py_uuid())

Try changing the last line to:

    session.auth = Storage(hmac_key=web2py_uuid(), user=True)

You might also want to change the condition to:

    if session.logged_in and not 'auth' in session:

Anthony

T.R.Rajkumar

unread,
Jun 24, 2017, 2:38:22 AM6/24/17
to web2py-users
Yes, perfect Anthony. Thanks a lot for forbearing with me. Anyway it is my pleasure to learn from the group.

I put the above code in my login action as below. It is working perfectly.


from gluon.storage import Storage
from gluon.utils import web2py_uuid
def login():
    form = FORM(TABLE(
            TR('User Name:',INPUT( _name='txtUName',_id='txtUName',requires=[IS_NOT_EMPTY(),IS_LENGTH(6,6),IS_MATCH('^e\d{5}',error_message='not valid user name.')])),
            TR('Password:', INPUT (_name='txtPwd', _id='txtPwd', _type='password',requires=[IS_NOT_EMPTY(),IS_LENGTH(8,6)])),
            INPUT (_type='submit',_value='Login')
                    )
               )
    msg=''
    if form.process(keepvalues=True).accepted:
       
        lcUname = form.vars.txtUName
        lcPwd = form.vars.txtPwd       
        lnCode = 10
        lcMsg = 'y'
       
        from gluon.contrib.pysimplesoap.client import SoapClient
        client = SoapClient(wsdl="http://172.16.164.64/ws_ts2admin/ts2admin.asmx?WSDL")
        rs = client.ValidateLogin(lcUname, lcPwd, lnCode, lcMsg)
        rs1 = rs['ValidateLoginResult']
        ret_code = rs1['Code']
        ret_msg = rs1['Msg']
        #print ret_msg
        lcAppId = 'vb_cont'
        if ret_code == 1:
            rs2 = client.ValidateAppUser(lcUname,lcAppId)           
            rs3 = rs2['ValidateAppUserResult']
            rs4 = rs3['Code']
            if rs4 == 1:
                rows =  db.executesql("exec admin_get_user_details @lcUserName = ?",placeholders=([lcUname]),as_dict=True)
                for i in rows:
                    session.divn = i['amcdcod']
                    session.sec = i['amcscod']
                    session.unit = i['unitid']
                    session.logged_in = True
                    session.uname = lcUname
                    if 'auth' in session:
                        session.auth = None
                    if not 'auth' in session:
                        session.auth = Storage(hmac_key=web2py_uuid(), user=True)

                    redirect(URL('amc','new_contract'))
            else:
                response.flash ='Not a user of app.'
        else:
            response.flash = ret_msg
       
       
    return dict(form=form,msg=msg)

def logout():
    session.logged_in = None
    session.uname = None
    session.auth = None
    session.divn = None
    session.sec = None
    session.unit = None

T.R.Rajkumar

unread,
Jun 24, 2017, 4:21:37 AM6/24/17
to web2py-users
Now I have ant\other small hitch. When I logout the action logout is called and redirect to login page.

If I or another user logins in with the same browser window digital signature is not available in grid.

If I close the browser window and open the browser and login _signature is available.

How to get the _signature in the same window after logout/login.

Thank you in advance.

Anthony

unread,
Jun 24, 2017, 10:21:19 AM6/24/17
to web2py-users
To remove items from the session, don't simply set their values to None. In that case, the key will remain in the session, simply with None stored as its value. Instead, to get rid of a given item completely, delete it:

del session.auth

Alternatively, you could change the condition:


if not 'auth' in session:

to:

if not session.auth:

The first will be True only when there is no 'auth' key in session, but the second will be True even if there is an 'auth' key in session, as long as the value is Falsey (such as None).

Anthony

T.R.Rajkumar

unread,
Jun 27, 2017, 1:19:50 AM6/27/17
to web2py-users
Yes, Anthony I did del session.auth in logout action and it working fine. Thanks for all the input. I thought I cannot use the grid without auth. But now because of your help the dependency has been removed and I am on my own authentication. Thanks again.
Reply all
Reply to author
Forward
0 new messages