# Oracle APEX - Security Basics Series:  APEX Sessions

In order to understand Oracle APEX sessions, it is key to first understand what a session is and, perhaps even more importantly, why we need such a thing.

## **"Web" Sessions**

It all starts with the HTTP protocol and how it works. Designed in the early days of the Web to serve static documents. Every time a client sends a request, the server processes it, returns a response, and immediately closes the connection. It keeps no built-in record of past interactions, has no memory of who sent what, and views every single request as if it were coming from a completely blank slate.

Think of the web server as a hotel doorman with short-term memory loss. Every time you approach him to ask a question or request a room key, he greets you as a complete stranger. You have to explain who you are, state what you need, and once he answers, he immediately forgets you ever existed. When you walk up to him five seconds later, the exact same process repeats.

This is what is known as being **stateless**, meaning each request is independent and unrelated to the previous one.

The concept of a **session** in web development exists to bridge this gap. To avoid explaining who you are every single time, the doorman gives you a unique physical badge (a **Session ID**). Now, instead of introducing yourself from scratch, you just show the badge. The doorman looks up your badge number in his logbook (the session "box" where your previous information is stored) to instantly remember who you are and what you were doing.

Because the server now "remembers" us through this badge, the end result is a **stateful** experience for the user, even though underlying HTTP requests remain completely independent behind the scenes.

In Oracle APEX, this identifier (the Session ID) is passed directly as a URL parameter (called session), while additional authentication proof is sent transparently with each request via a secure token cookie.

Now that generic web sessions are clear, we can move on to understanding ORDS sessions, a critical part of the equation.

## ORDS Sessions

Oracle REST Data Services (ORDS) serves as the middle tier between the client browser and the Oracle Database. Unlike HTTP, standard database sessions are **stateful** and are essential for querying or manipulating database data. Since a web browser cannot connect directly to an Oracle database, ORDS steps in to bridge the gap.

Based on its configuration, ORDS establishes a connection pool containing a specific number of persistent database sessions. These connections remain open to the database, allowing incoming client requests to share the underlying database sessions to retrieve or modify data.

![ORDS connection pool diagram](https://cdn.hashnode.com/uploads/covers/664c5bdc4bbfabf0cde2b520/b698c118-88db-47d9-87a9-9c76b324cf1b.png align="center")

*Figure 1: ORDS database connection pooling architecture (Source: Oracle Documentation).*

All database connections in the ORDS connection pool authenticate using a single, low-privilege database user (e.g.:`APEX_PUBLIC_USER`), depending on how your instance is configured.

Because ORDS dynamically assigns available connections from this pool to incoming requests, there is no permanent or fixed correlation between an APEX session and a database session.

A user's next button click or page submit might execute on an entirely different database session than their previous request, much like commuting home along a different route every day. You still end up at the same destination, but the vehicle path along the way might be completely different.

Understanding this pool structure is critical, especially when working with advanced features like Virtual Private Database (VPD) or `SYS_CONTEXT` (storing session-level attributes for your application).

Because these database sessions are shared across different HTTP requests, an ORDS session is reused by multiple users over time. Connection pooling is a smart mechanism that allows hundreds or thousands of web users to share a small, optimized number of database connections—saving significant hardware resources and licensing costs.

However, this architecture introduces a crucial security consideration. **Relying on state left over in an underlying ORDS database session to control user access or data visibility is a serious security risk.** Because a previous request executed by another user might have set specific package variables or context values, the next user who gets assigned that recycled connection could inadvertently inherit those settings if they are not properly reset.

Since ORDS database sessions are shared and cannot track individual web user states on their own, we need another layer of abstraction: **APEX sessions**.

## APEX Sessions

The generic concept of a web session applies directly to an APEX session. All session-related information for a given user, along with their application activity, is transparently maintained by Oracle APEX out of the box.

If we strip it down to the basics, an APEX session is essentially just database tables storing key-value pairs. These tables hold values for session items you set while navigating, APEX collections created during page processing, authorization states, and temporary operational data.

To bring the whole architectural flow together:

1.  **Request:** Once authenticated, your browser sends the APEX Session ID in the URL and your session token in an APEX cookie.
    
2.  **Routing:** ORDS receives the HTTP request and routes it to the database through one of the available connections in the shared DB pool.
    
3.  **Context Switch & Execution:** Database context immediately switches from the low-privilege ORDS user to your application's **Parsing Schema**. APEX then binds the request to your specific APEX session state and executes all necessary page renders, region queries, or PL/SQL processes strictly within that schema's security boundaries.
    
4.  **Response:** The generated output—typically HTML for page renders or JSON for AJAX calls—is returned through ORDS to your browser, which then renders the result locally.
    

All of this happens in fractions of a second. Is it magic? To some, it certainly feels like it.
