Advanced Web Programming outside of APEX


Published on

Introduced in Oracle 8.1.6. the PL/SQL Web Toolkit provides a way to get build Internet (on Intranet) database-based websites, REST-like webservices and XML and JSON-like output to the Web.

In this session we will discuss how to provide security (avoid sql/injection, backlisting and whitelisting program access, etc.. ), to avoid unnecessary DB processing (use of client cache, ...),to add error management to your PL/SQL Web Toolkit programs and to make your website more Google friendly.

Presented at "Oracle PL/SQL Programming Conference 2010 Europe"

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Advanced Web Programming outside of APEX

  1. 1. Advanced Web Programming outside of APEX<br />Filipe Silva<br />Silva . Filipe @ gmail . com<br />Faculdade de Engenharia - Universidade do Porto<br />Portugal<br />
  2. 2. Advanced Web Programming outside of beyond APEX<br />Filipe Silva<br />Silva . Filipe @ gmail . com<br />Faculdade de Engenharia - Universidade do Porto<br />Portugal<br />
  3. 3. Brief review of PL/SQL Web Toolkit<br />Web Request processing<br />Security<br />Error management<br />Improve DB use<br />File upload/ download and generation<br />Best Practices<br />PL/SQL Gateways alternatives<br />Topics<br />
  4. 4. Some Examples<br />
  5. 5. Some Examples<br />
  6. 6. Some Examples<br />
  7. 7. Main Aplication:<br />Almost 2 million PL/SQL code lines<br />4 000 Java lines<br />120 000 calls to HTP<br />Framework:<br />240 000 PL/SQL code lines<br />1 300 Java lines<br />11 000 calls to HTP<br />Statistics for SIGARRA©<br />Documents generated<br />(at FEUP)<br />September<br />17-9-2010 : 1 230 493 (high)<br />05-09-2010: 196 595 (low)<br />month average: 555 868 /day<br />
  8. 8. The HTTP Server receives a request from a client browser (1)<br />…routes the request to the plsql gateway (adapter)<br />…that ”maps” the request to an Oracle DB call (2)<br />Web Request Processing<br />http://<http_server_name>:<port>/<dad>/<procedure>?<var1>=<value_var1><br />
  9. 9. Web Request Processing (cont.)<br />Use of PL/SQL Web Toolkit will create an output in a buffer array (3)<br />If no unhandled exception was raise a COMMIT is made at the end of the PL/SQL call<br />The plsql Gateway gets the OWA buffer content and sends it to the HTTP Server (some sanitization is made) (4)<br />…thatdeliverstheresult to theclient. (5)<br />
  10. 10. Allows to generate web content directly from Oracle (since 8.1.6)<br />Has direct access to the DB (no-round trip)<br />It’s easy to learn<br />Keeps all the code in the same place (backups,…)<br />You can keep all the files in DB<br />PL/SQL Web Toolkit<br />
  11. 11. PL/SQL Web Toolkit<br />HTP – write to OWA (Web) output<br />HTF – construct HTML (mainly)<br />OWA_CACHE - writescachingheadertags<br />OWA_UTIL - retrievesenvironment variables, write header,...<br />OWA_COOKIE – send and receive browser cookies<br />OWA_OPT_LOCK –handles optimistic lock<br />OWA_IMAGE – get coordinates from user click in image map<br />OWA_SEC – security programs<br />OWA_CUSTOM - authorize function<br />OWA_PATTERN – pattern matching<br />OWA_MATCH – pattern matching<br />OWA_TEXT - stringmanipulation<br />WPG_DOCLOAD – BLOBs and BFILEs downloads<br />
  12. 12. HTP.p<br />OWA_UTIL.mime_header<br />OWA_UTIL.redirect_url<br />OWA_UTIL.status_line<br />OWA_UTIL.http_header_close<br />OWA_UTIL.get_procedure<br />OWA_UTIL.get_cgi_env<br />WPG_DOCLOAD.download_file<br />PL/SQL Web Toolkit<br /><ul><li>OWA_COOKIE.send
  13. 13. OWA_COOKIE.get
  14. 14. HTF.escape_sc</li></li></ul><li>DECLARE<br />la_thepage SYS.HTP.htbuf_arr;<br />li_irows INTEGER; li_version INTEGER; <br /> la_name_arr OWA.vc_arr; la_value_arr OWA.vc_arr; li_num PLS_INTEGER := 0;<br />BEGIN<br /> li_version := OWA.initialize;<br /> OWA.init_cgi_env (li_num, la_name_arr, la_value_arr);<br /> HTP.p ('My output'); -- or call to a procedure that will generated HTP like calls<br /> irows := 99999999999;<br />OWA.get_page (thepage => la_thepage, irows => li_irows);<br />FOR i IN 1 .. li_irows<br />LOOP<br /> DBMS_OUTPUT.put_line (la_thepage (i));<br />ENDLOOP;<br />END;<br />Test Output<br />
  15. 15. DECLARE<br />(...)<br /> lv_cookies VARCHAR2 (2000) := 'TESTE=Teste;';<br />BEGIN<br />li_version := OWA.initialize;<br />OWA_COOKIE.init; -- so it will reload the cookies buffer<br /> la_name_arr (1) := 'HTTP_COOKIE';<br /> la_value_arr (1) := lv_cookies;<br /> li_num := li_num +1;<br /> OWA.init_cgi_env (li_num, la_name_arr, la_value_arr);<br /> my_program();<br /> irows := 99999999999;<br />OWA.get_page (thepage => la_thepage, irows => li_irows);<br />(...)<br />END;<br />Test Output with cookies<br />OWA_COOKIE.cookie<br /> RECORD (<br />name varchar2(4096),<br />vals vc_arr,<br />num_vals integer<br />)<br />PROCEDURE my_program IS <br />(...)<br />lrec_cookieOWA_COOKIE.cookie<br />BEGIN<br />(...)<br /> lrec_cookie := OWA_COOKIE.get ('TESTE');<br />IF lrec_cookie.num_vals > 0<br />THEN<br />HTP.p ('Cookie value:' || lrec_cookie.vals (1));<br />ENDIF;<br />(...)<br />END;<br />
  16. 16. Needs ACL (access control list) permissions in 11g<br />Allows HTTP callouts from PL/SQL and SQL<br />Takes a URL as parameter and returns corresponding Webpage<br />Request :data is returned in the form of pieces, each piece is varchar2(2000)<br />Request Pieces: all pieces obtained at once as a table type of Varchar2(2000)<br />UTL_HTTP<br />
  17. 17. DECLARE<br />l_request UTL_HTTP.req; l_responseUTL_HTTP.resp;<br />(…)<br />BEGIN<br />UTL_HTTP.set_proxy (proxy => ‘myproxy‘, no_proxy_domains => ‘dom1,dom2'); <br />l_request := UTL_HTTP.begin_request ('http://someurl’ ,method => 'GET'); <br />UTL_HTTP.set_header (l_request, 'User-Agent', 'Mozilla/4.0');<br />l_response := UTL_HTTP.get_response (l_request);<br />DBMS_OUTPUT.put_line (' HTTP response: status code: ' || l_response.status_code ||<br />' reason phrase: ' || l_response.reason_phrase);<br />read_header ();<br />read_lines ();<br />UTL_HTTP.end_response (l_response);<br />END;<br />UTL_HTTP<br />PROCEDURE read_header IS<br />lv_header_name VARCHAR2 (256);<br />lv_header_value VARCHAR2 (1024);<br /> BEGIN<br /> FOR i IN 1 .. UTL_HTTP.get_header_count (l_response)<br /> LOOP<br />UTL_HTTP.get_header (l_response, i, <br />lv_header_name, lv_header_value);<br />DBMS_OUTPUT.put_line (lv_header_name || ': ' || lv_header_value);<br /> END LOOP;<br />END read_header;<br /> PROCEDURE read_lines IS<br />lv_line VARCHAR2 (32767);<br /> BEGIN<br /> LOOP<br />UTL_HTTP.read_line (l_response, lv_line);<br />DBMS_OUTPUT.put_line (lv_line);<br /> END LOOP;<br /> EXCEPTION<br /> WHEN UTL_HTTP.end_of_body<br /> THEN<br /> NULL;<br />END read_lines;<br />
  18. 18. Read RSS<br />ReadWebservices (REST, …)<br />ReadWebpages<br />Get Documents via URL <br />Example: crawling sites to index by Oracle Text <br />…<br />UTL_HTTP: Uses<br />
  19. 19. HTTP is a “stateless” protocol<br />Means credentials have to go with every request (i.e. cookies)<br />Should use SSL for everything requiring authentication (https)<br />Important answer status<br />200 – ok<br />204 – no content<br />304 – not modified<br />403 – forbidden<br />404 – not found <br />About HTTP<br />
  20. 20. Improve DB use (1)<br />HTTP Requests Types<br />HTTP request types supported:<br />GET – parameters passed by query string (URL)<br />POST – parameters passed by HTTP Request body<br />(large amount of data, file uploads, password forms, etc..)<br />HEAD – like GET but web server only returns header info<br />So...only return header info and exit the procedure!<br /> (…) –- send header<br />IF OWA_UTIL.get_cgi_env ('REQUEST_METHOD') = ‘HEAD'<br /> THEN<br /> RETURN;<br /> END IF;<br /> (…) –- send content<br />
  21. 21. DAD configuration<br /> PlsqlErrorStyle – use ApacheStyle in production systems <br /> PlsqlExclusionList - Blacklist<br />default: sys.*, dbms_*, utl_*, owa_*, owa.*, htp.*, htf.*<br /> PlsqlRequestValidationFunction – blacklist or whitelist<br />booleanfunction_name (procedure_name IN varchar2) <br />Security MOD_PLSQL<br />
  22. 22. FUNCTIONmy_validation_check (procedure_nameINVARCHAR2)<br />RETURNBOOLEAN<br />IS<br /> li_check PLS_INTEGER;<br />BEGIN<br /> SELECT 1<br /> INTO li_check<br /> FROM my_pages<br /> WHERE name = UPPER (procedure_name);<br />RETURNTRUE;<br />EXCEPTION<br /> WHEN NO_DATA_FOUND<br /> THEN<br />RETURNFALSE;<br />END my_validation_check;<br />PlsqlRequestValidationFunction<br />
  23. 23. Use a whitelist Web procedure table<br />Best practices (0)<br />
  24. 24. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><br /><html><br /><head><br /><title>Hello world</title><br /><link rel="stylesheet" href="mystyle.css"><br /></head><br /><body><br /> Hello World!<br /></body><br /></html><br />HTML<br />
  25. 25. Why?<br />HTML code in lowercase letters, and NEVER skip closing tags (like </p>)<br />Parsing errors => stop parse!<br />Not supported by totally of HTF (and HTP)<br />XHTML<br />
  26. 26. Make your own HTP and HTF packages<br />The new HTP must call sys.HTP to send the buffer to the OWA Output and use the same buffer types<br />Create procedures for new tags, opening and closing tags<br />Delete/comment obsolete tags<br />XHTML complain (lower case, close tags, …)<br />Add ‘class’ attribute to tags (…)<br />Allow buffer control<br />Read without changing it (or clean it)<br />Manipulation<br />For instance, if you need to get some storage buffer (3 columns divs problem)<br />Best practices (1)<br />
  27. 27. Text files<br />CSS<br />JSON <br /><br /><br />etc..<br />XML<br />RSS<br /><br />etc..<br />What else?<br />
  28. 28. PDF<br />PL_FPDF -,1337<br />PL/PDF - €<br />AS_PDF -<br />Youcanalsomanipulateimage files using Oracle interMedia<br />To createthumbnails<br />Putwatermark (11.2)<br />…<br />What else?<br />
  29. 29. QrCode<br /><br />ZIP (BLOBs)<br />What else?<br />
  30. 30. owa_util.mime_header('application/'); <br />Use SYLK or even HTML!!<br />SYLK is a text-based interchange format for spreadsheets; it supports formulas, borders, fonts, point sizes, etc. <br />Or CSV (Comma Separated File) (mime-type: text/csv) <br />PL/SQL ExcelDocumentType<br /><br />PL/XLS-XML €<br /><br />Excel<br />
  31. 31. SVG (XML)<br />FusionCharts<br />Needgraphics?<br />
  32. 32. DAD configuration: PlsqlDocumentTablename - the table name for storing documents when file uploads are performed through the DAD<br />Table definition:<br />NAME VARCHAR(128) UNIQUE NOT NULL,<br />MIME_TYPE VARCHAR(128),<br />DOC_SIZE NUMBER,<br />DAD_CHARSET VARCHAR(128),<br />LAST_UPDATED DATE,<br />CONTENT_TYPE VARCHAR(128),<br />[[CONTENT LONG RAW], -- files with extensions in PlsqlUploadAsLongRaw <br />[BLOB_CONTENT BLOB]] – other files<br />(...) – can have more columns<br />File upload<br />
  33. 33. HTML:<br /><form enctype="multipart/form-data" action=“my_pack.my_proc" method="POST"><br /><input type="file" name=“p_my_file“ /><br />(...)<br />In DB:<br />procedure my_proc (p_my_file IN varchar2, …) is<br />lrt_docdocuments_table%ROWTYPE;<br />begin<br /> select * <br /> into lrt_doc<br /> from documents_table<br /> where name=p_my_file;<br />(…)<br />File upload<br />
  34. 34. Do not keep documents in the uploaded documents table<br />Avoid collisions<br />Provide distinct access privileges<br />Backup polices<br />Distinct Business logic<br />…<br />Best practice (2)<br />
  35. 35. 1) Send Header info<br />OWA_UTIL.mime_header(prt_doc.mime_type, FALSE);<br /> -- specify mime_type and do not close header<br />HTP.p ('Last-Modified: ' ||pv_last_updated); -- allow cache<br />HTP.p ('Content-Length: ' ||prt_doc.doc_size); -- download info<br />HTP.p ('Content-disposition: attachment; filename=“'||<br />prt_doc.filename||'” '); -- “save As”<br />OWA_UTIL.http_header_close; --close header<br />File download<br />
  36. 36. 2) Send Data<br />2a) If BLOB call:<br />DECLARE<br />lb_lob BLOB := prt_doc.content; -- due to need to be an IN OUT<br />BEGIN<br />WPG_DOCLOAD.download_file (p_blob => lb_lob);<br />END;<br /> 2b) If CLOB:<br />DECLARE<br />lb_lob BLOB := clob_util.clob2blob (p_clob); <br />BEGIN<br />WPG_DOCLOAD.download_file (p_blob => lb_lob);<br />END;<br />File download<br />
  37. 37. DECLARE<br />offset PLS_INTEGER;<br /> len PLS_INTEGER;<br /> amount PLS_INTEGER := 32000;<br />BEGIN<br /> len := NVL (DBMS_LOB.getlength (c_lob), 0);<br />FOR i IN0 .. len / amount<br />LOOP<br /> offset := (amount * i) + 1;<br />HTP.prn(DBMS_LOB.SUBSTR(c_lob, amount , offset));<br />ENDLOOP;<br />END;<br />File download<br />Or2b) If CLOB<br />
  38. 38. FUNCTION clob2blob (p_clob IN CLOB) RETURN BLOB DETERMINISTICIS<br /> lbl_blob BLOB;<br /> li_dest_offset INTEGER := 1; li_src_offset INTEGER := 1;<br /> li_amount INTEGER := DBMS_LOB.lobmaxsize;<br /> ln_blob_csid NUMBER := DBMS_LOB.default_csid;<br /> li_lang_ctx INTEGER := DBMS_LOB.default_lang_ctx;<br /> li_warning INTEGER;<br /> BEGIN<br /> DBMS_LOB.createtemporary (lob_loc => lbl_blob, cache => TRUE, dur =>;<br /> DBMS_LOB.converttoblob (dest_lob => lbl_blob<br /> ,src_clob => p_clob<br /> ,amount => li_amount<br /> ,dest_offset => li_dest_offset<br /> ,src_offset => li_src_offset<br /> ,blob_csid => ln_blob_csid<br /> ,lang_context => li_lang_ctx<br /> ,warning => li_warning);<br /> RETURN lbl_blob;<br /> END clob2blob;<br />CLOB 2 BLOB<br />
  39. 39. An Example:<br />OWA_UTIL.mime_header ('text/css', FALSE); -- sends mime-type<br /> -- and doesn’t closes the header<br />HTP.P ('Last-Modified: ' || lv_updated_date); <br />HTP.P ('Cache-Control: public, s-maxage=300, max-age=86400');<br />-- or <br />-- HTP.p ('Cache-Control: private, max-age=86400');<br />--or<br />-- HTP.p (‘Cache-Control: no-cache’); --or even no-store<br />OWA_UTIL.http_header_close; --close the header<br />(…)<br />Cache – Last Modified<br />
  40. 40. -- Thu, 30 Sep 2010 16:03:22 GMT<br />lv_updated_date :=TO_CHAR (<br />SYS_EXTRACT_UTC (<br /> CAST (NVL (pd_last_modified, SYSDATE)<br /> AS TIMESTAMP)),<br /> 'Dy, DD Mon YYYY HH24:MI:SS',<br /> 'NLS_DATE_LANGUAGE=''AMERICAN''')<br /> || ' GMT';<br />Last-Modified<br />
  41. 41. Then I can check if the browser has the document in cache<br />IF OWA_UTIL.get_cgi_env ('HTTP_IF_MODIFIED_SINCE') =<br />lv_updated_date<br /> THEN<br />OWA_UTIL.status_line (nstatus => 304,<br />creason => 'Not Modified',<br />bclose_header => TRUE);<br />RETURN;<br /> END IF;<br />Improve DB use (2)<br />
  42. 42. Can also use ETag:<br />HTP.p('ETag: ' || lv_file_etag);<br /> -- or owa_cache.set_cache(p_etag, p_level); <br /> --  length(lv_file_etag)<= 55<br />And to check:<br />OWA_UTIL.get_cgi_env('HTTP_IF_NONE_MATCH')<br />--needs PlsqlCGIEnvironmentList HTTP_IF_NONE_MATCH<br />Cache - ETag<br />
  43. 43. Pseudo-Code<br /><ul><li>Check if it’s in client cache
  44. 44. -> if so return status 503 -> exit
  45. 45. Output HTTP (Response) header info
  46. 46. If HEAD request
  47. 47. -> exit
  48. 48. Output Content</li></ul>Best Practices (3)Improve DB use (1+2)<br />
  49. 49. If a page can only be access by a POST form -> check it!<br />owa_util.get_cgi_env( 'REQUEST_METHOD' ) =‘POST’ and owa_util.get_cgi_env( 'HTTP_REFERER‘) is not null <br />-- maybe even check that the referer is from the same site or an exact page …<br />If a page is only to be access by a AJAX -> check it!<br />OWA_UTIL.get_cgi_env ('X-Requested-With') is not null<br /> -- needs DAD PlsqlCGIEnvironmentList X-Requested-With<br />But an hacker can avoid that if they know of it <br />Disallow Access<br />
  50. 50. begin<br />(…)<br />exceptions<br />(…)<br />whenothersthen<br />qem_web.register_error;<br />end;<br />Error Manager<br />
  51. 51. Error Manager<br />
  52. 52. Error Manager<br />
  53. 53. Error Manager<br />
  54. 54. Avoid reporting system messages that the normal user cannot understand but an hacker could use (Error message SQL Injection). (i.e SQLERRM, …)<br />The errors should be reported to a system maintainer even if the user doesn’t report them.<br /> Should have enough information to replicate the error.<br /> We based our solution on Quest Error Manager (<br />Error Manager<br />
  55. 55. Quest Error Manager<br />Log 4 PLSQL<br />Logger<br />PL/SQL Log & DBugLibrary<br />PLJ_LG<br />…<br />Error and Log Libraries<br />
  56. 56. Have an error handler for when others in every procedure that will generate your web pages<br />The ones that are to called by URL<br />They are in a whitelist table, right?<br />With PL/Scope (11g) you can have a script that check the use of your error report program inside the procedures<br />Best Pratices (4)<br />
  57. 57. The OWASP Top 10 Web Application Security Risks for 2010 are: <br />A1: Injection <br />A2: Cross-Site Scripting (XSS) <br />A3: Broken Authentication and Session Management <br />A4: Insecure Direct Object References <br />A5: Cross-Site Request Forgery (CSRF) <br />A6: Security Misconfiguration <br />A7: Insecure Cryptographic Storage <br />A8: Failure to Restrict URL Access <br />A9: Insufficient Transport Layer Protection <br />A10: Unvalidated Redirects and Forwards <br />Security<br />
  58. 58. One of the more devastating attacks on a web application<br />One of the most common attacks<br />Probably the most popular technique used for database intrusion caused by inefficient input validation<br />Some real World examples (2005-2010):<br /><br />SQL injection: what?<br />
  59. 59. PROCEDUREmy_bad_proc (v inVARCHAR2) IS<br />TYPE cursortyp ISREFCURSOR;<br />cursordual cursortyp;<br /> result_v VARCHAR2 (300);<br /> sql_stmt VARCHAR2 (300);<br />BEGIN<br />sql_stmt := 'select * from dual where dummy=''' || v || ''';<br /> DBMS_OUTPUT.put_line (sql_stmt);<br />OPEN cursordual FOR sql_stmt;<br />LOOP<br />FETCH cursordual INTO result_v;<br />EXITWHEN cursordual%NOTFOUND;<br /> DBMS_OUTPUT.put_line (result_v);<br />ENDLOOP;<br />END my_bad_proc;<br />Sql injection: example<br />BEGIN<br />my_bad_proc(v=><br /> 'aaa'' <br /> union <br /> select login from logins --<br />END;<br />select * from dual where dummy='aaa'<br /> union<br /> select login from logins --<br />……<br />Mark<br />Steven<br />(…)<br />
  60. 60. In Oracle when concatenating non-constants to be used as a statement in<br />EXECUTE IMMEDIATE v_string;<br />OPEN v_cursor FOR v_string;<br />DBMS_SQL.parse (..., v_string, …)<br />Safe code: <br />SELECT … INTO …<br />And above if not concatenating with non- constants<br />OPEN … USING var1, var2,…<br />EXECUTE IMMEDIATE …. USING var1, var2,…<br />DBMS_SQL.bind_variable<br />SQL Injection: where?<br />
  61. 61. We need to convert the Text value to a SQL text Literal.<br />If needed by design replace all the quotation marks with two quotations<br /> replace(v,'''','''''')<br /> -- for instance to allow O’Neil<br />Use DBMS_ASSERT.ENQUOTE_LITERAL:<br />Enclose the literal with quotation<br />Check with DBMS_ASSERT.enquote_literal the validy catching the exception VALUE_ERROR it raises if invalid<br />OR<br />Use DBMS_ASSERT.enquote_literal to enclose the literal with in quotation marks and it raises VALUE_ERROR if invalid.<br />Best Pratices (4)<br />
  62. 62. PROCEDUREmy_good_proc1 (v inVARCHAR2) IS<br /> (…)<br /> lv_literal VARCHAR2(100):='''' || REPLACE (v, '''', '''''') || '''';<br />BEGIN<br /> BEGIN<br />lv_literal :=sys.DBMS_ASSERT.enquote_literal(lv_literal );<br /> EXCEPTION<br />WHENVALUE_ERROR<br />THENDBMS_OUTPUT.put_line ('Value entered invalid');<br />RETURN;<br /> END;<br /> sql_stmt := 'select * from dual where dummy=' || lv_literal;<br /> OPEN cursordual FOR sql_stmt;<br /> (…)<br />END my_good_proc1;<br />DBMS_ASSERT.enquote_literal (1)<br />
  63. 63. PROCEDUREmy_good_proc2(v VARCHAR2)<br />IS<br /> (…)<br />BEGIN<br /> BEGIN<br /> sql_stmt := 'select * from dual where dummy=' <br /> ||sys.DBMS_ASSERT.enquote_literal(v);<br /> EXCEPTION<br />WHENVALUE_ERROR<br />THEN<br /> DBMS_OUTPUT.put_line ('Value entered invalid');<br />RETURN;<br /> END;<br />OPEN cursordual FORsql_stmt;<br />(...)<br />END my_good_proc2;<br />DBMS_ASSERT.enquote_literal (2)<br />
  64. 64. PROCEDUREmy_good_proc2(v VARCHAR2)<br />IS<br /> (…)<br />BEGIN<br /> BEGIN<br /> sql_stmt := 'select * from dual where dummy=‘<br /> ||sys.DBMS_ASSERT.enquote_literal(REPLACE (v, '''', '''''') );<br /> EXCEPTION<br />WHENVALUE_ERROR<br />THEN<br /> DBMS_OUTPUT.put_line ('Value entered invalid');<br />RETURN;<br /> END;<br />OPEN cursordual FORsql_stmt;<br />(...)<br />END my_good_proc2;<br />DBMS_ASSERT.enquote_literal (2)<br />
  65. 65. DBMS_ASSERT<br />SIMPLE_SQL_NAME<br />QUALIFIED_SQL_NAME<br />SCHEMA_NAME<br />SQL_OBJECT_NAME<br />ENQUOTE_LITERAL – single quotes check<br />ENQUOTE_NAME – double quotes check<br />
  66. 66. Protect the database and web server (patches)<br />Use minimum privileges<br />AUTHID CURRENT_USER when possible<br />Use of prepared statement<br />Data API<br />Sanitize Input:<br />from users<br />URL parameters<br />Cookies<br />avoid cursor injection (11g):<br />DBMS_SQL.open_cursor(security_level => 2);<br />SQL Injection: Prevention<br />
  67. 67. The OWASP Top 10 Web Application Security Risks for 2010 are: <br />A1: Injection <br />A2: Cross-Site Scripting (XSS) <br />A3: Broken Authentication and Session Management <br />A4: Insecure Direct Object References <br />A5: Cross-Site Request Forgery (CSRF) <br />A6: Security Misconfiguration <br />A7: Insecure Cryptographic Storage <br />A8: Failure to Restrict URL Access <br />A9: Insufficient Transport Layer Protection <br />A10: Unvalidated Redirects and Forwards <br />Security<br />
  68. 68. XSS is a form of injection where the interpreter is the browser and attacks are “buried” in the HTML document<br />Cross-Site Scripting (XSS)<br />
  69. 69. Sanitize input<br />HTML Escapeuntrusted data (htf.escape_sc)<br />if HTML input allowed…check it<br />Use the new Content Security Policy header<br />Examples:<br />If no external script and no inline-script<br />X-Content-Security-Policy: allow 'self'; <br />If inline script exists but no external script<br />X-Content-Security-Policy: allow 'self'; options inline-script;<br />Cross-Site Scripting (XSS): Prevention<br />
  70. 70. Avoid iframe/frame<br />X-Frame-Options: [deny | sameOrigin]<br />X-Content-Security-Policy: frame-src: ...<br />HTTPOnly cookie flag (OAS version >=<br />...<br />Cross-Site Scripting (XSS): Prevention (cont.)<br />
  71. 71. The OWASP Top 10 Web Application Security Risks for 2010 are: <br />A1: Injection <br />A2: Cross-Site Scripting (XSS) <br />A3: Broken Authentication and Session Management <br />A4: Insecure Direct Object References <br />A5: Cross-Site Request Forgery (CSRF) <br />A6: Security Misconfiguration <br />A7: Insecure Cryptographic Storage <br />A8: Failure to Restrict URL Access <br />A9: Insufficient Transport Layer Protection <br />A10: Unvalidated Redirects and Forwards <br />Security<br />
  72. 72. Password Strength<br />Password storage encrypted<br />Login attemps restricted (by time/tries)<br />Avoid Cross-Site Scripting (XSS)<br />No session Id in URL<br />Protecting Credentials in Transit: cookies secure (HTTPS)<br />AUTOCOMPLETE=OFF in authentication forms<br />…<br />Broken Authentication and Session Management : Prevention<br />
  73. 73. DBMS_EXPORT_EXTENSION<br />DBMS_CDC_IMPDP<br />DBMS_CDC_ISUBSCRIBE<br />DBMS_CDC_SUBSCRIBE<br />DRILOAD<br />SDO_TOPO_DROP_FTBL SQL<br />LT<br />DBMS_METADATA<br />ALTER SESSION SET NLS_DATE_FORMAT (lateral SQL Injection)<br />Advice: check Oracle Security bugs<br />
  74. 74. Mod_plsql in Oracle HTTP Server (since 8i) (Build on Apache 1.3 or 2.2)<br />Embedded PL/SQL Gateway (DBMS_EPG) <br />Apex Listener<br />Doug McMahon’s Mod_owa<br />Thoth Gateway in Microsoft Internet Information Server<br />DBPrism Servlet engine (Tomcat,…) <br />JOPA Gateway Servlet(Tomcat,…) <br />Total Knowledge’s Mod_plsql<br />Alternative PL/SQL Gateways<br />
  75. 75. Web Request processing<br />File upload/ download and generation<br />Best Practices<br />HTP/HTF replacer<br />Error management<br />Improve DB use (HEAD, client file caching)<br />Security<br />Black listing, white listing<br />How to avoid SQL Injection<br />PL/SQL Gateways alternatives<br />Summary<br />
  76. 76. Questions?<br />Filipe Silva<br />Silva . Filipe @ gmail . com<br />Blog: Label: Oracle Blues<br />Faculdade de Engenharia - Universidade do Porto<br />Portugal<br />Thanks for listening!<br />