0% found this document useful (0 votes)
49 views

Koletzke Lock It Down PLSQL Security Features

This document discusses security features in PL/SQL for locking down application functions and data access. It covers techniques like bind variables, code assertion using DBMS_ASSERT to add quotes and validate SQL names, and building SQL dynamically with flexible column names. The document provides examples of how SQL injection can occur and how these techniques can help prevent it. It also discusses general security planning and safeguards like application roles and privileges.

Uploaded by

jlc1967
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views

Koletzke Lock It Down PLSQL Security Features

This document discusses security features in PL/SQL for locking down application functions and data access. It covers techniques like bind variables, code assertion using DBMS_ASSERT to add quotes and validate SQL names, and building SQL dynamically with flexible column names. The document provides examples of how SQL injection can occur and how these techniques can help prevent it. It also discusses general security planning and safeguards like application roles and privileges.

Uploaded by

jlc1967
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Good to Remember

Lock it Down:
PL/SQL Security Features for
Code Assertion, VPD, and We will bankrupt ourselves
Encryption in the vain search for
absolute security.
Peter Koletzke
Technical Director & —Dwight David Eisenhower,
Principal Instructor (1890–1969)

Scope Agenda
• In scope – 10g &11g PL/SQL techniques: • Introduction
– Data access A bit about 12c
– Functional access later, if time • Locking down application functions
– Encryption • Locking down data
• Not in scope - security techniques:
– OS, web or application server, file systems • New 12c features
– Denial of service (DOS) • Further study
– Cross-site Scripting (XSS)
– Parameter manipulation, session hijacking,
buffer overflow
3 4
Security Planning General Safeguards
• Need to develop test plans early on, • Application roles and privileges
design into system – Users in roles
– Who can do what, who can see what – Roles granted to application functions
– Application security fits into an overall plan • Application uses a non-privileged “user”
• Risk/exposure/safeguards account
• Test roles, functions, data – Not application table owner account
• Coding standards – User account cannot do DDL
• How not to handle security: roll your • Restrict access to DML (including SELECT)
to application tables
own
• Think about how users could foil safeguards
– Better: use prebuilt techniques
– For example, SQL injection
• Vendors have certified and tested them
5 6

Agenda What is SQL Injection?


• Introduction • An attempt to add unintended clauses
to a SQL statement
• Locking down application functions – For example, a search field on a web form
• Locking down data – The value entered is used for the query:
• Adds search criteria to a WHERE clause OR
• New 12c features • Passed as a parameter to a PL/SQL function

• Further study

7 8
Simple Example “Bad” User Does This
• Search form field for “Last Name” • Fills in Last Name field as:
– Example query to process the field '||last_name; DELETE FROM employees
SELECT email, first_name WHERE 1=1||'
FROM employees • SQL becomes
WHERE last_name ='||F_LastName||'; SELECT email, first_name
• User is supposed to enter a name like FROM employees
WHERE last_name = ''|| last_name;
“Hunold”
DELETE FROM employees WHERE 1=1||'';
SELECT email, first_name
FROM employees
WHERE last_name = 'Hunold';

9 10

PL/SQL Function Also Vulnerable SQL Injection Cure 1:


8i+
PROCEDURE find_emp( Bind Variables
p_last_name IN VARCHAR2,
p_email OUT VARCHAR2, • The most important technique
p_first_name OUT VARCHAR2)
IS SELECT email, first_name
v_stmt VARCHAR2(2000); FROM employees
BEGIN
v_stmt := 'SELECT email, first_name '|| WHERE last_name = :p;
'FROM employees '||
'WHERE last_name = '''|| p_last_name||'''; • Reason: statement is parsed before the
--
EXECUTE IMMEDIATE v_stmt INTO p_email, p_first_name;
bind variable value is substituted
END find_emp; – The value is always treated as a value, not
part of the statement
• Same value passed into p_last_name
• Same in PL/SQL
will have the same results ( )
11 12
PL/SQL Bind Variable Building SQL Dynamically
PROCEDURE find_emp( PROCEDURE find_emp(
p_last_name IN VARCHAR2, p_col_1 IN VARCHAR2,
p_email OUT VARCHAR2, p_col_1_value IN VARCHAR2,
p_first_name OUT VARCHAR2) p_email OUT VARCHAR2)
IS IS
v_stmt VARCHAR2(2000); v_stmt VARCHAR2(2000);
BEGIN BEGIN
v_stmt := 'SELECT email, first_name '|| v_stmt := 'SELECT email '||
'FROM employees '|| 'FROM employees '||
'WHERE last_name = :p'; 'WHERE '||p_col_1||' = :p';
-- --
EXECUTE IMMEDIATE v_stmt INTO p_email, p_last_name EXECUTE IMMEDIATE v_stmt INTO p_email
USING p_last_name; USING p_col_1_value;
END find_emp; END find_emp;

• Value passed in as a value, • The column name needs to be flexible


not as a SQL clause
• SQL injection danger if you concatenate SQL
13 14

SQL Injection Cure 2: DBMS_ASSERT Examples


10g+
Code Assertion • ENQUOTE_LITERAL()
• Confirm that the component you – Adds quotes and checks for spurious quotes in the
concatenate is a SQL object value
• Use the DBMS_ASSERT package – VALUE_ERROR exception
• SIMPLE_SQL_NAME()
– ENQUOTE_LITERAL()
– Checks that the name could be used for a SQL
• To safely add quotes around a value
object
– SIMPLE_SQL_NAME() – SYS.DBMS_ASSERT.INVALID_SQL_NAME
• To ensure the name is a real database object exception
– E_ENCODE_ERROR • Always lead with SYS schema prefix
• Exception raised when there is a violation of the – Ensures the proper user’s package is run
assertion
15 16
Adding Quotes Checking for Valid SQL Name
DECLARE DECLARE
v_value VARCHAR2(200); v_value VARCHAR2(200);
BEGIN BEGIN
v_value := 'HARRY'; OK
v_value := 'EMPLOYEES';
OK
DBMS_OUTPUT.PUT_LINE(v_value||' =
DBMS_OUTPUT.PUT_LINE(v_value|| '||SYS.DBMS_ASSERT.SIMPLE_SQL_NAME(v_value));
' = '||SYS.DBMS_ASSERT.ENQUOTE_LITERAL(v_value)); v_value := '2EMPLOYEES';
v_value := 'HARRY'''; DBMS_OUTPUT.PUT_LINE(v_value|| Error
DBMS_OUTPUT.PUT_LINE(v_value|| Error ' = '||SYS.DBMS_ASSERT.SIMPLE_SQL_NAME(v_value));
v_value := 'EMPLOYEES''';
Error
' = '||SYS.DBMS_ASSERT.ENQUOTE_LITERAL(v_value));
EXCEPTION DBMS_OUTPUT.PUT_LINE(v_value||
' = '||SYS.DBMS_ASSERT.SIMPLE_SQL_NAME(v_value));
WHEN VALUE_ERROR EXCEPTION
THEN WHEN SYS.DBMS_ASSERT.INVALID_SQL_NAME
DBMS_OUTPUT.PUT_LINE('Invalid value!'); THEN
END; DBMS_OUTPUT.PUT_LINE('Invalid name!');
END;

17 18

Agenda Techniques for Protecting Data


• Introduction • Data filtering
– DBMS_RLS package
• Locking down application functions • Data hiding (masking)
• Locking down data – DBMS_RLS package
– DBMS_REDACT package
• New 12c features • Encryption
• Further study – Oracle Transparent Data Encryption
– DBMS_OBFUSCATION_TOOLKIT and
DBMS_CRYPTO packages

19 20
Data Filtering How To: Data Filtering 8i+
• Objective • Virtual Private Database (VPD)
– Users should see and interact with only the – A.k.a., Fine-grained Access Control (FGAC)
data they should see and interact with
• Not to be confused with Fine Grain Auditing (FGA)
• More granular than table grants to roles or
users – F.k.a., Row-Level Security (RLS) Oracle
Enterprise
• Examples – Implemented through DBMS_RLS Edition only
– HARRY can only see employee data from • Components
department 10 – Package function to return a WHERE clause
– AHUNOLD can only see employee data from
departments 60 – Policy object (created with DBMS_RLS) for a
– NKOCCHAR can only see employee data table
from department 100 • Associates function to table Grant to EXECUTE on
DBMS_RLS needed
21 22

About the Policy Policy


BEGIN
• Database object that links a table to a SYS.DBMS_RLS.ADD_POLICY (
object_schema => Null
filtering function ,object_name => 'EMPLOYEES'
,policy_name => 'EMPLOYEES_POL'
• Visible in USER_POLICIES ,function_schema => Null
– SELECT * FROM user_policies ,policy_function => 'POLICY_PKG.EMP_POL'
,statement_types =>
• Create, alter, and drop using DBMS_RLS 'SELECT,INSERT,UPDATE,DELETE'
,policy_type => dbms_rls.dynamic
– Not DDL as such ,long_predicate => TRUE
,update_check => FALSE
,static_policy => FALSE
,enable => TRUE );
END;

23 24
About the Filtering Function Filtering Function
FUNCTION emp_pol(
obj_schema IN VARCHAR2,
• Logic that returns a predicate (WHERE obj_name IN VARCHAR2)
clause component); examples: IS
RETURN VARCHAR2

– department_id IN (<privs>) v_predicate VARCHAR2(1000);


BEGIN
• <privs> are stored in an application table IF user = 'HR'
– 1=1 or just '' THEN
v_predicate := '';
• All rows ELSIF v_user = 'HARRY'
THEN
– 1=2 v_predicate := 'department_id = 10';
ELSE -- No access
• No rows v_predicate := '1=2';
END IF;
• The predicate is automatically --
added to all queries for the table RETURN v_predicate;
END emp_pol;

25 26

Process 1 harry Application Security Policy Steps


SELECT *
1. The application issues the query.
Application  FROM employees
2. Database policy code adds a WHERE
Security 
Tables
2 clause predicate based on the user
VPD Policy  and security table entry
Code 3. The query is run.
3
Application  4. Results return to the application.
3
Data Tables SELECT *
FROM employees
WHERE dept_no IN (60,90)

4
Results

27 28 28
Variation: Application Context Writing to Application Context
• Accessible memory variable area for • DBMS_SESSION.SET_CONTEXT(context_
each session; has a name 8i+ name, variable_name, value)
– Like SYS_CONTEXT('USERENV', – Can only store VARCHAR2 variables
'SESSION_USER') – Must be in context’s package
• USERENV is the context area
• For example,
• Secure
– Memory variables only available to session – ON_LOGON trigger can store username
for use in policy
– Can only be updated through a single
PL/SQL package – Web application writes the logged in app
CREATE CONTEXT hr_context user into the context
USING policy_pkg; • Uses the same database user for database
login
29 30

Reading from App Context Filtering Function


-- same as earlier example emp_pol function but
• SYS_CONTEXT(context_name, -- instead of hard coding user names, query
-- from a table that holds user privileges
variable_name) Protect obj_name with
v_predicate := 'department_id IN ( '|| DBMS_ASSERT
– Can be read from anywhere in the session 'SELECT access_values '||
'FROM user_table_access '||
• Even SQL
'WHERE table_name = '||obj_name||
– Session-specific ' AND username = '||
'SYS_CONTEXT(''HR_CONTEXT'','||
• Variables are created when they are assigned '''USERNAME''))';
• Variables and values disappear when session RETURN v_predicate;
ends
USER_TABLE_ACCESS
• Read variables in the policy function
– Protects against hacking of policy code

31 32
Process with App Context Application Security Policy Steps
ON_LOGON trigger OR
web application code
harry 2 harry 1. The application saves the logged-in
1
user name to the “application context”
Application  SELECT *
Context 
harry
FROM employees 2. The application issues the query.
Application  3
Security Tables 3 3. Database policy code adds a WHERE
VPD Policy  clause predicate based on the user
Code name in the app context and security
4 table entry
Application  4 SELECT *
Data Tables
FROM employees 4. The query is run.
WHERE dept_no IN (60,90)
5. Results return to the application.
5
Results
33 34 34

Sample Context Assignments Debugging Policy Code


CREATE OR REPLACE TRIGGER emp_tr • No helpful feedback
AFTER LOGON ON DATABASE • Usually
BEGIN – “ORA-28113: policy predicate has error”
hr.policy_pkg.set_hr_context; – Sometimes 28110, 28112
END emp_tr
• Look in trace file in user_dump_dest
folder
• In ADF – For example:
– Application module impl Java file C:\oracle\db\diag\rdbms\orcl\orcl\trace
• Call function in prepare_session() method

35 36
Big Note Techniques for Protecting Data
• VPD policy always • Data filtering
applied EXCEPT to: – DBMS_RLS package
– SYS or any user • Data hiding (masking)
connected "as – DBMS_RLS package
sysdba" – DBMS_REDACT package
– An account granted
• Encryption
EXEMPT ACCESS
POLICY – Oracle Transparent Data Encryption
– DBMS_OBFUSCATION_TOOLKIT and
DBMS_CRYPTO packages

37 38

VPD Can Hide Data, Too Policy


BEGIN
10g+ SYS.DBMS_RLS.ADD_POLICY (
object_schema => Null
• “Column masking” ,object_name => 'EMPLOYEES'
,policy_name => 'EMPLOYEE_HIDING_POL'
– Hides data in specific columns ,function_schema => Null
• Same setup ,policy_function =>
'POLICY_PKG.RESTRICT_COLUMNS_POL'
– Database function ,statement_types => 'SELECT'
– Policy associates function to table ,policy_type => dbms_rls.dynamic
,long_predicate => TRUE
• DBMS_RLS to create the policy ,sec_relevant_cols => 'COMMISSION_PCT,SALARY'
,sec_relevant_cols_opt => dbms_rls.all_rows
,update_check => FALSE
,static_policy => FALSE
,enable => TRUE );
END;
39 40
Function Another Data Hiding Option
FUNCTION restrict_columns_pol(
obj_schema IN VARCHAR2, • Oracle Data Redaction 11.2.0.4+
obj_name IN VARCHAR2)
RETURN VARCHAR2
– DBMS_REDACT
IS
v_predicate VARCHAR2(1000);
• Can substitute replacement characters
BEGIN for the redacted value
IF USER = 'HARRY' HARRY will see – Full or partial value
THEN Salary as null.
v_predicate := '1=2';
END IF;
• Does not require a policy function
-- – Filtering parameter in
RETURN v_predicate;
END restrict_columns_pol; DBMS_REDACT.ADD_POLICY
• Restricts SELECT only Grant to EXECUTE on
– VPD works for all DML DBMS_REDACT needed

41 42

Create Policy A Variation


BEGIN BEGIN
DBMS_REDACT.add_policy( DBMS_REDACT.add_policy(
object_schema => 'HR' object_schema => 'HR'
,object_name => 'EMPLOYEES' ,object_name => 'EMPLOYEES'
,column_name => 'SALARY' ,column_name => 'SOCIAL_SECURITY_NUMBER'
,policy_name => 'redact_salary_pol' ,policy_name => 'redact_ssn_pol'
,function_type => DBMS_REDACT.partial
,function_type => DBMS_REDACT.full
,expression => '1=1'
,expression => '1=1'
,function_parameters => 'VVVVFVVFVVVV,VVVV-VV-VVVV, *,1,8'
,policy_description => 'redact the salary to all'
,policy_description => 'show only last 4 SSN'
);
);
END;
END;

• Always redacts data in this column • Returns partially redacted value


– display character, start, end
• SALARY returns as 0 – *******8765’
43 44
More About Redaction Techniques for Protecting Data
• Bypass by granting EXEMPT REDACTION • Data filtering
POLICY to user (not role) – DBMS_RLS package
– Contained in DBA role already • Data hiding (masking)
• Support for regular expressions – DBMS_RLS package
• Can generate random replacement – DBMS_REDACT package
strings • Encryption
– Oracle Transparent Data Encryption
– DBMS_OBFUSCATION_TOOLKIT and
DBMS_CRYPTO packages

45 46

Encryption By TDE More About TDE


10gR2+
10gR2+
• Column-level encryption – except:
• Oracle Transparent Data Encryption – LOB columns, foreign key columns, non-B-
tree indexes, range scan through index,
– Database option materialize view logs, others
• Encrypts “data at rest” – Performance hit: 6-15% depending on #
– Data in data files ONLY columns
11gR1+
• Adds tablespace encryption
• Data in and out of database is plain text
– All data in the tablespace is encrypted
– Rely on network encryption to secure – Performance hit: “10% max”
messages
• Set up a “wallet” (a file)
• No option for conditional encryption – Add an encryption key to the wallet
– Needs DBA setup – When instance starts, open wallet (make it
part of database startup script)
47 48
Column Encryption Tablespace Encryption
CREATE TABLE employees (
CREATE TABLESPACE emp_encrypt
employee_id
NUMBER CONSTRAINT emp_pk PRIMARY KEY, DATAFILE 'c: hr\encrypt01.dbf' SIZE 64M
social_security_number ENCRYPTION USING 'AES256'
VARCHAR2(11) ENCRYPT USING 'AES256' SALT); DEFAULT STORAGE(ENCRYPT);

• Default algorithm (method) is AES192 • Still need a wallet


– Others available: 3DES168, AES128, AES256
• “Salt” adds random string before encryption • Good if most columns need encryption
– Most secure – Remember performance hit, though
– Cannot apply “salt” to indexed columns
• 1-52 bytes increase per encrypted value • No storage increase
• Choose column encryption if 5% or less columns
need encryption

49 50

TDE Notes Encrypting Data Using PL/SQL


• Adding encryption to existing table 8i-9i • DBMS_OBFUSCATION_TOOLKIT
– This can take some time
– Replaced by DBMS_CRYPTO
– Drop indexes first
– Use DBMS_CRYPTO for 10g+
– Data is encrypted but unencrypted copy
10g+ • DBMS_CRYPTO
persists in data file
– Need to move table to a new tablespace – More encryption algorithms
– Then drop old tablespace file securely – Easier to use API

• Removing encryption
ALTER TABLE employees MODIFY (
social_security_number DECRYPT);

51 52
DBMS_CRYPTO Custom Encryption Package
CREATE OR REPLACE PACKAGE BODY crypto_pkg
• NOT TRANSPARENT! AS
-- Key used for SYS.DBMS_CRYPTO calls.
– This is “roll your own” folks -- This would be queried from a table which would encrypt the
-- value using a second key. DO NOT embed a plain text string here.
– You need to write code for encrypting and g_crypto_key CONSTANT RAW(32) := 'ABCDEF';
decrypting --
-- Encryption type used for SYS.DBMS_CRYPTO calls
– You need to store the encryption key g_encryption_type CONSTANT PLS_INTEGER :=
somewhere -- Advanced Encryption Standard 256-bit key
SYS.DBMS_CRYPTO.ENCRYPT_AES256 +
• https://oracle-base.com/articles/9i/storing- -- Cipher block chaining mode
passwords-in-the-database-9i SYS.DBMS_CRYPTO.CHAIN_CBC +
-- Padding of Password-Based Cryptography
– DBMS_CRYPTO.RANDOMBYTES() can -- Standard #5
SYS.DBMS_CRYPTO.PAD_PKCS5;
generate the key

53 54

Encrypt CLOB Decrypt CLOB


FUNCTION encrypted_clob( FUNCTION decrypted_clob(
p_decrypted_clob CLOB) p_encrypted_blob BLOB)
RETURN BLOB RETURN CLOB
IS IS
v_encrypted_blob BLOB; v_decrypted_clob CLOB;
BEGIN -- initialize the target BEGIN
DBMS_LOB.CREATETEMPORARY(v_encrypted_blob, TRUE); -- initialize the target
-- DBMS_LOB.CREATETEMPORARY(v_decrypted_clob, TRUE);
SYS.DBMS_CRYPTO.ENCRYPT( --
dst => v_encrypted_blob, SYS.DBMS_CRYPTO.DECRYPT(
src => p_decrypted_clob, dst => v_decrypted_clob,
typ => g_encryption_type, src => p_encrypted_blob,
key => g_crypto_key typ => g_encryption_type,
); -- leave iv as the default key => g_crypto_key
-- ); -- leave iv as the default
RETURN v_encrypted_blob; --
EXCEPTION ... RETURN v_decrypted_clob;
END encrypted_clob; EXCEPTION ...
END decrypted_clob;
55
Agenda Granting Role to PL/SQL Unit
• APPOWNER.PACKAGE_SEC
• Introduction – Invoker’s rights (AUTHID CURRENT_USER)
12cR1+
– Accesses the SECURITY_TAB table
• Locking down application functions • INSERT, UPDATE, DELETE, SELECT
• END_USER1
– Granted EXECUTE on the package
• Locking down data • APPOWNER creates role: SECURITY_ACCESS
• GRANT SELECT ON security_tab TO
• New 12c features security_access;
• GRANT security_access TO package_sec;
• Further study • END_USER1 calls PACKAGE_SEC
– Can only SELECT from SECURITY_TAB
– Cannot run DELETE, INSERT, UPDATE procedures in
SECURITY_TAB

57 58

INHERIT PRIVILEGES Invoker Rights Example


• Protects against invoker rights 12cR1+ CREATE FUNCTION emp_name(
p_emp_id employees.employee_id%TYPE)
RETURN VARCHAR2
problems AUTHID CURRENT_USER
IS
– Defined with AUTHID CURRENT_USER v_name VARCHAR2(100);
BEGIN
• Scenario SELECT first_name||' '||last_name
INTO v_name
– Users run a function defined by Dave, a FROM hr.employees
developer – everything works WHERE employee_id = p_emp_id;
--
– DBA Frank runs the function IF USER = 'FRANK'
THEN
• Disaster EXECUTE IMMEDIATE 'DELETE FROM SYS.COL$';
• Dave’s function runs under the privileges of Frank END IF;
RETURN v_name;
END emp_name;
This is “privilege inheritance”

59 60
INHERIT PRIVILEGES ACCESSIBLE BY Clause
• All users have this automatically 12cR1+ • Defines the PL/SQL code that can 12cR1+
run for their account: access the package
GRANT INHERIT PRIVILEGES on USER <user> TO
PUBLIC; – CREATE FUNCTION
– Everyone can access everything with invoker’s – CREATE PACKAGE
rights as before – CREATE PROCEDURE
• Dave can revoke that – CREATE TYPE
REVOKE INHERIT PRIVILEGES on USER <user> TO – ALTER TYPE
PUBLIC;
CREATE OR REPLACE PACKAGE util_pkg
– Calling the preceding function would fail ACCESSIBLE BY (
• Then grant to a single dba, Sally PACKAGE emp_pkg,
GRANT INHERIT PRIVILEGES on USER dave TO
sally;
PACKAGE policy_pkg,
TRIGGER emp_tr)
61 62

Agenda Thanks for the Memories


• Introduction
Knowledge is of two kinds.
• Locking down application functions
We know a subset ourselves,
• Locking down data or we know where we can
• New 12c features find information upon it.
• Further study — Samuel Johnson (1709-1784),
letter

63 64
Further Study PL/SQL Security Wall
• Steven Feuerstein – 12c new PL/SQL features
– http://www.oracle.com/technetwork/issue-archive/2013/13-
sep/o53plsql-1999801.html
• Tom Kyte – SQL injection
– http://tkyte.blogspot.com/2012/02/all-about-security-sql- DBMS_RLS DBMS_REDACT DBMS_ASSERT
injection.html
• Bryn Llewelyn - SQL injection
– http://www.oracle.com/technetwork/database/features/plsql/overvie Data filtering & hiding Data hiding Anti-SQL injection
w/how-to-write-injection-proof-plsql-1-129572.pdf
• Oracle Learning Library
– oracle.com/oll
• PL/SQL Challenge
– plsqlchallenge.oracle.com
• Live SQL
– http://www.oracle.com/technetwork/database/application- DBMS_CRYPTO DBMS_OBFUSCATION_TOOLKIT
development/livesql/index.html
• Practically Perfect PL/SQL – Feuerstein videos
– https://www.youtube.com/channel/UCpJpLMRm452kVcie3RpINPw Encryption Encryption

65 66

Summary Please fill out the evals


• Design security in from the start
Some of 8 books co-
• DBMS_ASSERT to foil SQL injection authored with Dr. Paul
• Virtual Private Database to filter data Dorsey, Avrom Roy-
Faderman, & Duncan Mills
• DBMS_RLS, DBMS_REDACT to hide
data
• TDE, DBMS_OBFUSCATION_TOOL- Designer
Developer
Advanced
Forms & JDeveloper 3

KIT and DBMS_CRYPTO to encrypt


Handbook Reports Handbook
http://www.quovera.com
• Founded in 1995 as Millennia Vision
• Study advice from the experts Corp.
ORACLE9i ORACLE • More technical white papers and
• Safe coding to all! JDeveloper
Handbook
JDeveloper 10g
Handbook
presentations on the web site

67 69

You might also like