Service Portal Approval Widget Permissions problem

meghansmith
Kilo Expert

The OOB Service Portal approvals page doesn't apparently check permissions.   If an EOS user has the link to a specific approval page (such as "sp?id=approval&table=sysapproval_approver&sys_id=${sys_id}") from somebody sharing an email or link with them, then that EOS user, who is NOT the designated approver can approve requests.   Has anybody else run into this?   This is a major flaw, in my opinion.

1 ACCEPTED SOLUTION

You can use $sp.canReadRecord(gr) to check whether user has permissions to read the record. If the user does not have access then the method witll return false. Based on this value hide the Approve & Reject buttons


View solution in original post

12 REPLIES 12

ashwinkumar_pat
Giga Expert

Hello Meghan,



Here is what happened with my instance...



The approval request is assigned to user X.


User Y who doesnt have any roles, tried accessing the approval record using the URL - sp?id=approval&table=sysapproval_approver&sys_id={sys id}


The record was not visible but the approve / rejects buttons on "Approval Info" widget were visible. When I clicked approved, the approval record was approved !!!



You are right. This should not happen. What it actually did is - The client script of "Approval Info" widget made a call to server using update() function. The ACLs should have been checked before updating the record. This is a flaw in server.update() function. This actually makes me think that all three functions i.e. update(), refresh() and get() functions bypass the authorization. If this is true and we are right about it, then it is a major security issue.


Please highlight this issue to ServiceNow immediately.


find_real_file.png


var gr = $sp.getRecord();     -> Return the GlideRecord



if (input && input.op && gr) {         => this block gets executed when the client script makes a server.update() call


      gr.state = input.op;


      gr.update();


}




This is the server code that gets executed when I click on approve button. So it basically calls the GlideRecord.update() function.


This answers why the authorization was not applied. GlideRecord does not respect ACLs GlideRecordSecure do (my understanding, I may be wrong).



Now the question is -> should $sp.getRecord() return GlideRecordSecure instead of GlideRecord?


It would be interesting to know what ServiceNow thinks about this.



I would appreciate if you keep this thread posted with ServiceNow's response.


Hi Ashwinkumar,



I've opened a ticket with Hi about this and will keep you posted with their response.   Thanks for looking into it and confirming the problem.



Sincerely,



Meghan Smith


Hello Ashwinkumar,



The response from Hi was disappointing.  



PRB751143 has been opened asking development to address this so I have attached it to this incident so we notify you if a fix is released. As a work around you can add a role to the Approvals page or to the relevant widgets.


I let them know I don't consider this a workaround.   It involves giving everybody who is anybody's manager a role, and then any approver can still modify any approval assigned to anybody.   I'm working with our consultant from Crossfuze to come up with an actual solution.   If Hi gives a better response, or if the problem is resolved, I'll update again.



Sincerely,



Meghan Smith