Handling Files Safely in APEX
File uploads and downloads are common features in business applications, from attaching documents to work orders to downloading generated reports. APEX provides built-in mechanisms for both, but implementing them securely requires attention to authorization, file type validation, and storage management.
Secure File Upload
Use the File Browse item type for uploads. Configure it with an allowed file types list to restrict what users can upload:
-- After upload, move from temp storage to your table
DECLARE
l_blob BLOB;
l_filename VARCHAR2(400);
l_mime_type VARCHAR2(255);
BEGIN
SELECT blob_content, filename, mime_type
INTO l_blob, l_filename, l_mime_type
FROM apex_application_temp_files
WHERE name = :P10_FILE_UPLOAD;
-- Validate file type server-side (don't trust client-side only)
IF l_mime_type NOT IN ('application/pdf','image/png','image/jpeg',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') THEN
RAISE_APPLICATION_ERROR(-20001, 'File type not allowed.');
END IF;
-- Validate file size
IF DBMS_LOB.GETLENGTH(l_blob) > 10 * 1024 * 1024 THEN
RAISE_APPLICATION_ERROR(-20002, 'File exceeds 10 MB limit.');
END IF;
INSERT INTO document_attachments (doc_id, file_name, mime_type, file_content, uploaded_by, uploaded_dt)
VALUES (:P10_DOC_ID, l_filename, l_mime_type, l_blob, :APP_USER, SYSDATE);
-- Clean up temp file
DELETE FROM apex_application_temp_files WHERE name = :P10_FILE_UPLOAD;
END;
Secure File Download
Never expose direct file URLs with predictable IDs. Instead, use an APEX download process that checks authorization before serving the file:
-- Page process: Download Attachment (On Demand or Before Header)
DECLARE
l_blob BLOB;
l_filename VARCHAR2(400);
l_mime_type VARCHAR2(255);
BEGIN
SELECT file_content, file_name, mime_type
INTO l_blob, l_filename, l_mime_type
FROM document_attachments
WHERE attachment_id = :P10_ATTACHMENT_ID
AND doc_id IN (SELECT doc_id FROM documents
WHERE owner = :APP_USER OR :APP_USER IN
(SELECT username FROM doc_access WHERE doc_id = documents.doc_id));
SYS.HTP.P('Content-Disposition: attachment; filename="' || l_filename || '"');
OWA_UTIL.MIME_HEADER(l_mime_type, FALSE);
SYS.HTP.P('Content-Length: ' || DBMS_LOB.GETLENGTH(l_blob));
OWA_UTIL.HTTP_HEADER_CLOSE;
WPG_DOCLOAD.DOWNLOAD_FILE(l_blob);
APEX_APPLICATION.STOP_APEX_ENGINE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20003, 'File not found or access denied.');
END;
Storage Considerations
Store files in BLOB columns with SecureFiles storage for compression and deduplication. For very large file volumes, consider Oracle’s DBFS (Database File System) or external object storage with DBMS_CLOUD. Implement a cleanup process to purge orphaned files from temp storage and expired attachments from your tables.