Skip to main content

Command Palette

Search for a command to run...

Security in Oracle APEX: Strategies to Prevent SQL Injection and XSS Attacks

Why Security Is Essential for Excellence in Oracle APEX

Updated
6 min read
Security in Oracle APEX: Strategies to Prevent SQL Injection and XSS Attacks

🇪🇸 Leer en Español

💼 For IT Managers & Decision Makers

  • Business Problem: Data leaks and unauthorized access destroy brand reputation; proactive security prevents fraud and safeguards user trust.

  • Operational Efficiency: Implementing native APEX security defenses reduces manual code auditing time by 70% and prevents costly post-release vulnerability fixes.

  • Developer Action: If you are a developer, skip directly to the code below!

In our previous APEX Insights article, we covered ten key recommendations for building robust and maintainable Oracle APEX applications. Now, it's time to go deeper into the most critical pillar of all: security.

Oracle APEX provides a highly secure architecture by design, but the PL/SQL and JavaScript we write can introduce vulnerabilities. The two most common attacks you must defend against are SQL Injection (server-side) and Cross-Site Scripting (XSS) (client-side).

Mastering these defenses is essential for delivering world-class APEX applications.


🚨 The Server Enemy: SQL Injection

SQL Injection occurs when attackers inject malicious SQL through user-controlled input, forcing the database to execute unintended commands.

🔑 The Golden Rule: Always Use Bind Variables

Never concatenate user input into SQL strings. Always use bind variables (:PXX_ITEM). This ensures values are treated as data, not executable code.

If you're still using concatenation in PL/SQL, it's time to refactor.

❌ Vulnerable Example

DECLARE
    l_user_id VARCHAR2(50) := :P1_USER_ID;
BEGIN
    EXECUTE IMMEDIATE 'UPDATE users SET status = ''ACTIVE'' '
        || 'WHERE user_id = ''' || l_user_id || '''';
END;

✅ Safe Example

BEGIN
    UPDATE users SET status = 'ACTIVE' WHERE user_id = :P1_USER_ID;
END;

🛡 Dynamic SQL: Use APEX_EXEC

APEX_EXEC.EXECUTE_SQL(
  p_sql_statement => 'UPDATE users SET status = :P_STATUS WHERE user_id = :P_USER_ID',
  p_bind_vars     => APEX_EXEC.T_BIND_VAR(
    APEX_EXEC.T_BIND_VAR_ROW('P_STATUS', 'ACTIVE'),
    APEX_EXEC.T_BIND_VAR_ROW('P_USER_ID', :P1_USER_ID)
  )
);

🕷 The Client Enemy: Cross-Site Scripting (XSS)

XSS happens when malicious JavaScript is injected through user input and executed in another user's browser.

🔒 Declarative Defense: Escape Special Characters

Oracle APEX provides strong declarative protection. Always ensure user-entered values are escaped:

  • Page Items: Use safe item types. Avoid HTML-rendering items for untrusted content.

  • Classic / Interactive Reports: Enable Escape special characters.

🧹 PL/SQL Defense: APEX_ESCAPE.HTML_OUT

Use APEX_ESCAPE when building HTML in PL/SQL.

❌ Vulnerable

htp.p('Welcome, ' || :P1_USER_NAME);

✅ Safe

htp.p('Welcome, ' || APEX_ESCAPE.HTML_OUT(:P1_USER_NAME));

🔄 Secure AJAX Calls with apex.server.process()

Never construct AJAX requests manually. Always use Oracle APEX JavaScript APIs—they automatically pass the session checksum.

const payload = {
  x01: $v("P1_NEW_VALUE"),
  f01: ["value1", "value2"],
};

apex.server.process(
  "PROCESS_SAVE_DATA",
  {
    dataType: "json",
    x01: payload.x01,
    f01: payload.f01,
  },
  {
    success: function (pData) {
      if (pData.success) {
        apex.message.showPageSuccess("Data saved successfully.");
      }
    },
    error: function (jqXHR, textStatus, errorThrown) {
      apex.message.showErrors([
        {
          type: "error",
          message: `Processing error: ${errorThrown}`,
          location: ["page"],
        },
      ]);
    },
  },
);

🛡️ Hardening AJAX Callbacks with Authorization Schemes

Using apex.server.process() on the client side is only half the battle. If a malicious actor bypasses your client-side UI, they can still trigger the underlying AJAX Callback process directly.

To prevent unauthorized execution, you must secure the AJAX Callback at the server level:

  1. Declarative Protection: Always associate a native Authorization Scheme directly to the AJAX Callback process in the Page Designer.

  2. Programmatic Assertion (PL/SQL): Inside your AJAX Callback code, perform a secure programmatic check using APEX_AUTHORIZATION.IS_AUTHORIZED as a secondary line of defense.

Here is the professional PL/SQL pattern to secure your callback:

-- Secure AJAX Callback Process: "PROCESS_SAVE_DATA"
DECLARE
    l_has_access BOOLEAN;
BEGIN
    -- 1. Programmatic Authorization Scheme Assertion
    l_has_access := APEX_AUTHORIZATION.IS_AUTHORIZED(
        p_authorization_name => 'EDIT_SALES_RECORDS'
    );

    IF NOT l_has_access THEN
        -- Log unauthorized attempt and return a secure JSON error
        APEX_DEBUG.WARN(
            'Unauthorized AJAX callback execution attempt by user: %s',
            :APP_USER
        );

        APEX_JSON.OPEN_OBJECT;
        APEX_JSON.WRITE('success', FALSE);
        APEX_JSON.WRITE('error', 'Access Denied: Insufficient Privileges.');
        APEX_JSON.CLOSE_OBJECT;
        RETURN;
    END IF;

    -- 2. Secure processing of validated data
    UPDATE sales_leads
       SET status = :x01
     WHERE id = :P1_RECORD_ID;

    APEX_JSON.OPEN_OBJECT;
    APEX_JSON.WRITE('success', TRUE);
    APEX_JSON.CLOSE_OBJECT;
EXCEPTION
    WHEN OTHERS THEN
        APEX_JSON.OPEN_OBJECT;
        APEX_JSON.WRITE('success', FALSE);
        APEX_JSON.WRITE('error', 'An unexpected error occurred.');
        APEX_JSON.CLOSE_OBJECT;
END;

🔗 Secure Redirects with APEX_UTIL.PREPARE_URL

Always include a session checksum when building dynamic URLs.

🔐 Safe PL/SQL Redirect

DECLARE
    l_url VARCHAR2(4000);
BEGIN
    l_url := APEX_UTIL.PREPARE_URL(
        p_url    => 'f?p=' || :APP_ID || ':2:' || :APP_SESSION,
        p_items  => 'P2_DEPARTMENT,P2_RECORD_ID',
        p_values => 'SALES,' || :P1_CURRENT_ID,
        p_checksum_type => 'SESSION'
    );

    APEX_UTIL.REDIRECT_URL(p_url => l_url);
END;

🧩 Conclusion

Security in Oracle APEX is a shared responsibility. The platform protects architecture and sessions, but developers must secure PL/SQL and JavaScript.

By consistently applying:

  • Bind variables

  • Output escaping

  • Secure AJAX calls and Authorization Schemes

  • Safe redirects

you're building a stronger, safer, more professional Oracle APEX application.

📚 Going Deeper

Ready to go deeper? Read our next article in the series: Advanced Security in Oracle APEX: Architecting for Resilience to learn about enterprise security, Web Credentials, and Access Control Lists (ACLs).


📋 The 5-Minute Quick Audit Checklist

Before you stage your changes or click that "Deploy" button, print or save this 5-minute quick security checklist to verify each of your pages:

  • [ ] Bind Variables Check: Did I search for EXECUTE IMMEDIATE or Dynamic SQL in page processes, packages, or computations and verify that all user inputs use bind variables (:ITEM_NAME) or APEX_EXEC instead of string concatenation?

  • [ ] Escape Special Characters: Are all Interactive Grids, Interactive Reports, and Classic Reports configured with "Escape special characters" = YES on any columns rendering text entered by users?

  • [ ] Page Item Restrictions: Are all read-only or hidden items that shouldn't be modified by the user configured with Session State Protection = Restricted?

  • [ ] AJAX Callback Authorization: Does every single AJAX Callback process on the page have an Authorization Scheme assigned declaratively, and does the PL/SQL code assert APEX_AUTHORIZATION.IS_AUTHORIZED at the start?

  • [ ] Safe Redirects & URLs: Are all dynamic redirects built using APEX_UTIL.PREPARE_URL with p_checksum_type => 'SESSION' to guarantee URL tampering protection?

What security challenge have you solved in your APEX projects? Share your insights below.

Don't miss next week's APEX Insights article—where we'll explore how to improve user experience (UX) in Oracle APEX.


🚀 Elevate Your APEX Architecture

Is technical debt slowing down your database backends or exposing security holes? I help enterprise teams build secure, scalable, and high-performance Oracle APEX applications.


📘 References

  1. Oracle APEX Secure Coding Guidelineshttps://docs.oracle.com/en/database/oracle/application-express/latest/htmig/securing-an-application.html

  2. OWASP Top 10 (A03: Injection, A07: XSS)https://owasp.org/www-project-top-ten/

  3. Oracle APEX JavaScript API (apex.server.process)https://docs.oracle.com/en/database/oracle/application-express/latest/aexjs/apex.server.html