Skip to Main Content
Feature Request FR-3729
Product Area Page Components
Status CLOSED

2 Voters

Submitted page items in authorization schemes at page level

andrea galizzi Public
· Apr 10 2024

Idea Summary
Enable the authorization shemes at page level to read the submitted item values during the submit of the page.

Use Case
I created a public demo application to better explain what I mean:

Let's imagine I have a report (page 1), and a "form" type page (page 2) that allows the user to modify one row at a time.
In each row of the report, there is an "edit" button that links to the form page passing the row ID as URL parameter (for example: P2_ID).

The user can only edit some rows (based on the status of the row).
So the "edit" button is shown only when a specific condition is matched. For example (PL/SQL expression): 

CAN_EDIT(P_ID => :ID, P_USER => :APP_USER)

Now, I want to do the same check on the form page.
To do so, I create an authorization scheme (with "PL/SQL Function Returning Boolean" type):

RETURN CAN_EDIT(P_ID => :P2_ID, P_USER => :APP_USER);

This authorization scheme works great... but not anywhere!

  • Page rendering → Works (because the P2_ID item is setted by the URL parameter).
  • Process during rendering → Works
  • Region rendering → Works
  • Region refresh → Works (because the P2_ID is submitted as specified in the "Page Items to Submit" setting).
  • Page submit → Fails (this happens because the page authorization scheme is checked before loading the items value from the submit request. P2_ID is null, so the check fails). 
  • Process during submit → Works
  • Process (AJAX callback) → Works

Objection 1: remove the authorization scheme on the page and just use the checksum protection
No, the session checksum isn't enough.
The P2_ID item has the "Value Protected" option enabled, and the "Session State Protection" at "Checksum Required - Session Level".

  1. The user open the page and edit the row 1.
  2. The status of the row 1 changes. The user cannot edit it anymore.
  3. Using the browser navigation history, the user can go back to the URL with session checksum that sets P2_ID=1.

Objection 2: store the P2_ID value in session
No, setting the "Storage" option at "Per Session (Persistent)" on the P2_ID item is not an option, because I want the user to use multiple tabs at the same time.

  1. User open the row 1. P2_ID session value = 1.
  2. User open the row 2 in a new tab. P2_ID session value = 2.
  3. User save the row 1. Authorization scheme check with P2_ID=2 when editing the row 1. This is not correct.

The APEX_CLONE_SESSION option cannot help because the "Rejoin Session" app setting is set at "Enabled for All Sessions".

Preferred Solution
APEX should update the page item session values (with the new submitted values) BEFORE running the page authorization schema.

This is a great idea! You can already achieve this in APEX today with a slightly different approach.

Comments

Comments

  • jayson hanes Admin OP 2.1 years ago

    Hi @andrea galizzi from our review it appears that this needs further discussion to understand better. Could you please recreate this as a post on https://apex.oracle.com/forum for this purpose?

  • andrea galizzi OP 2.1 years ago

    Hi @jayson hanes, done. The post can be found here.

  • andrea galizzi OP 1.9 years ago

    You can already achieve this in APEX today with a slightly different approach.

    Please, tell me how then.

    As now, the authorization schemas simply do not work during page submission if they refer to a page item.


    The simplest solution I can think of is:

    Removing the page-level authorization scheme and adding it to every validation/process. It is ugly but… ok, I can do it. But then, how do I block the access to the page (rendering)? Do I have to create a custom process that show a custom error page if the user has {not [my authorization scheme]}?

    (In my opinion, it literally means replicating the "authorization scheme" property of the page… but in a worse/more complicated way).

    Is there really no better way?

  • carsten.czarski APEX Team OP 1.9 years ago

    Hi Andrea,

    the authorization scheme can not really use the values from the page submit, as these cannot be trusted. 

    • A URL attribute is protected against tampering by the checksum, so nobody can simply change the value which was once generated into a URL.
    • A page submit does not contain checksums - the meaning of a page submit is to send changed values to the server. It's on the server processing to make sure that these are processed correctly. 

    However, a page authorization scheme which is dependent on item values from the page submit could easily be circumvented by simply intercepting the submit operation in the browser and changing the HTTP POST request - that would not be reliable at all. Note that people are building all sorts auf authorization schemes, and APEX must make sure that all these work correctly.

    I think, for your use case, the authorization must not be on the page level. You could add a Before Header Branch to your page which redirects to an error page, and which uses the NOT {Authorization Scheme}, so that the page first loads for the unauthenticated user, but immediately branches off to an error page.

    regards

    -Carsten

  • andrea galizzi OP 1.9 years ago

    Hi @carsten.czarski, thank you for your reply.

    The page item used is "hidden" with the "Value Protected" option enabled, so (in theory) could be trusted.
    Anyway, that's not the point for me.

    I always consider the values as untrusted.

    That's why I have an authorization scheme that checks if the value exists, is valid and the current user has the authorization to view/edit it.

    I don't care if the value of the item is somehow manually changed in JavaScript or at HTTP level.
    If the "original" page has P_ITEM = 1 and the submitted page has P_ITEM = 2... the authorization schema always checks if the submitted request is valid or not.
    If P_ITEM = 2 is valid then the check pass and the POST request can be processed.
    It means that the user could have easily navigate to the page with P_ITEM = 2 and do the exact same POST request.

    Unfortunately, the URL checksum isn't enough. I simply cannot trust it, because even in the same session the same URL can be valid or invalid based on the status of the row.

    | P_ITEM | Row editable | User is authorized | Desired result |
    | --- | --- | --- | --- |
    | 1 | Yes | Yes | Page access granted |
    | 1 | No | Yes | Page access denied (error page with specific message) |

    In conclusion, I would like to manage all of this using the page authorization scheme, but from what I understand, this is not possible.

    So I have to leave the page authorization scheme empty and add two custom application processes (because branches and validation can not be created on the global page):
    1. "On Load: Before Header" → Redirect to or show a custom error page.
    2. "On Submit: After Page Submission" → Add inline/page error with custom message.

    This way I can achieve the desired result.

    What I don't like about this solution is:
    1. The page authorization scheme is not set, so it seems like there is no authorization check involved in the page.
    2. The application processes are not displayed in Page Designer. So a new dev will have hard time understand that in these specif pages are executed two (very important) additional processes. (and that adding a new page process with a lower sequence will cause errors).