1 / 33

Program Analysis for Security

Program Analysis for Security. Suhabe Bugrara Stanford University. Web Application Code. 1. javax.sql.Connection con = . . .; 2. javax.servlet.http.HttpServletRequest request = . . .; 3. String username = request.getParameter(“username”); 4. String query = “SELECT * FROM Users “ +

Download Presentation

Program Analysis for Security

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Program Analysis for Security Suhabe Bugrara Stanford University

  2. Web Application Code 1. javax.sql.Connection con = . . .; 2. javax.servlet.http.HttpServletRequest request = . . .; 3. String username = request.getParameter(“username”); 4. String query = “SELECT * FROM Users “ + “ WHERE name = ‘” + username + ”’”; 5. con.execute(query);

  3. Program Analyzers need to be able to analyze large code bases Code Program Analyzer false alarm false alarm Spec potentially reports many warnings may emit false alarms

  4. Soundness, Completeness

  5. Complete Incomplete Reports all errors May report false alarms Reports all errors Reports no false alarms Sound Undecidable Decidable May not report all errors May report false alarms May not report all errors Reports no false alarms Unsound Decidable Decidable

  6. Manual testing only examines small subset of behaviors Entry Entry 1 1 2 2 4 4 1 3 4 1 1 1 2 4 1 3 4 1 2 4 1 3 4 2 2 3 1 2 3 1 2 4 1 3 4 1 2 4 1 2 3 1 3 4 4 4 1 2 3 1 2 3 1 3 4 . . . 1 2 4 1 2 4 1 3 4 Exit Exit Software Behaviors 6

  7. Sound Over-approximation of Behaviors Reported Error Modules . . . approximation is too coarse… …yields too many false alarms False Alarm Behaviors Software Traditional Static Analysis

  8. Does this program ever crash? entry X  0 Is Y = 0 ? yes no X  X + 1 X  X - 1 Is Y = 0 ? yes no Is X < 0 ? exit yes no crash

  9. Does this program ever crash? entry X  0 Is Y = 0 ? yes no X  X + 1 X  X - 1 Is Y = 0 ? yes no Is X < 0 ? exit yes no crash infeasible path! … program will never crash

  10. Try analyzing without approximating… entry X  0 X = 0 Is Y = 0 ? yes no X = 2 X = 1 X = 0 X  X + 1 X  X - 1 X = 2 X = 1 X = 3 X = 1 X = 2 Is Y = 0 ? X = 3 X = 1 X = 2 yes no Is X < 0 ? exit X = 3 yes no X = 2 X = 1 X = 3 crash non-termination! … therefore, need to approximate

  11. dataflow elements din X = 0 dout dout = f(din) X  X + 1 f X = 1 dataflow equation transfer function

  12. X = 0 din1 X  X + 1 dout1 = f1(din1) dout1 X = 1 dout2 dout1 = din2 din2 X = 1 f2 f1 Is Y = 0 ? dout2 = f2(din2) X = 1

  13. dout1 = f1(din1) dout2 = f2(din2) din2 f1 f2 djoin = dout1 ⊔dout2 din1 dout1 dout2 djoin = din3 djoin din3 dout3 = f3(din3) f3 dout3 least upper bound operator What is the space of dataflow elements, ? What is the least upper bound operator, ⊔?

  14. partially ordered set … { a, b, c } … 2 { a, b } { a, c } { b, c } X = 2 1 { a } { b } { c }  = ? ℤ X = 1 0 { } X = 0 -1 x  y means x y x ⊔ y = max(x, y)   X = -1 -2 … -2 neg -1 0 1 pos 2 … zero X = -2 …  … X = T  X = pos X = 0 X = neg X = 

  15. Try analyzing with “signs” approximation… entry X  0 X = 0 Is Y = 0 ? yes no X = 0 X = 0 X  X + 1 X  X - 1 X = pos X = neg X = T lost precision Is Y = 0 ? X = T X = T yes no Is X < 0 ? exit yes no X = T X = T crash terminates... … but reports false alarm … therefore, need more precision

  16. X = T X  neg X  pos true X = pos X = 0 X = neg Y = 0 Y  0 false X =  X = T refined signs lattice signs lattice Boolean formula lattice X = pos X = 0 X = neg X = 

  17. Try analyzing with “path-sensitive signs” approximation… entry X  0 true X = 0 Is Y = 0 ? yes no true X = 0 X = 0 true X  X + 1 X  X - 1 Y=0 X = pos X = neg Y0 no precision loss Is Y = 0 ? Y=0 X = pos Y0 X = neg yes X = neg Y0 no Y=0 X = pos Is X < 0 ? exit refinement yes no X = pos Y=0 crash terminates... … no false alarm … soundly proved never crashes

  18. Tainted Object Propagation taint source String username = req.getParameter(“username”); StringBuffer buf = new StringBuffer(); buf.append(“SELECT * FROM Users “); buf.append(“WHERE name = ‘”); buf.append(username); buf.append(“’”); String query = buf.toString(); con.execute(query); derivations taint sink

  19. Tainted Object Propagation

  20. Security Violation . . . o1 o2 ok taint sink taint source derived(o1,o2)

  21. Complication of Aliasing String username = req.getParameter(“username”); StringBuffer buf1 = new StringBuffer(); StringBuffer buf2 = buf1; buf1.append(username); String query = buf2.toString(); con.execute(query);  o . points-to(buf1,o)  points-to(buf2,o) analyzer must know about aliasing relationship between buf1 and buf2 to find vulnerability No security violation found!

  22. Statements

  23. Pointer Analysis

  24. Context Sensitivity String passedUrl = request.getParameter(“...”); DataSource ds1 = new DataSource(passedUrl); String localUrl = “http://localhost/”; DataSource ds2 = new DataSource(localUrl); String s1 = ds1.getUrl(); String s2 = ds2.getUrl(); StringBuffer buf1 = new StringBuffer(); buf1.append(s2); String query = buf1.toString(); Connection con = ...; con.execute(query); class DataSource { private String url; public DataSource(String url) { this.url = url; } String getUrl() { return this.url; } } false alarm!

  25. Complete Incomplete Reports all errors May report false alarms Reports all errors Reports no false alarms Sound Undecidable Decidable May not report all errors May report false alarms May not report all errors Reports no false alarms Unsound Decidable Decidable

  26. intbad_abs (int x) { if (x < 0) return –x; if (x == 12345678) return –x; return x; } Constraint (x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x) Solution x = -1

  27. intbad_abs (int x) { if (x < 0) return –x; if (x == 12345678) return –x; return x; } Constraint (x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x = 12345678) && (ret = -x)Solution x = 12345678

  28. intbad_abs (int x) { if (x < 0) return –x; if (x == 12345678) return –x; return x; } Constraint (x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x != 12345678) && (ret = x) Solution x = 4

  29. intbad_abs (int x) { if (x < 0) return –x; if (x == 12345678) return –x; return x; } KLEE automatically generated test cases for each path… x = -1 x = 12345678 x = 4

  30. 1: intsymbolic_bad_abs (int x) { 2: add_constraints(x >= INT_MIN, x <= INT_MAX); 3: ret = new symbol; 4: 5: if (fork() == child) { 6: add_constraints(x < 0, ret = -x); 7: return ret; 8://(x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x) 9: } else 10: add_constraints(x >= 0); 11: 12: if (fork() == child) { 13: add_constraints(x = 12345678, ret = -x); 14: return ret; 15: //(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x = 12345678) 16:// && (ret = -x) 17: } else 18: add_constraints(x != 12345678); 19: 20: add_constraints(ret = x); 21: return ret; 22: //(x >= INT_MIN) && (x <= INT_MAX) && (x >= 0) && (x != 12345678) 23:&& (ret = x) 24:}

  31. 1: intmain (void) { 2: unsigned i, t, a[4] = { 1, 3, 5, 2}; 3: make_symbolic(&i); 4: 5: if (i >= 4) 6: exit(0); 7: 8: char *p = (char *) a + i * 4; 9: *p = *p – 1; 10: 11: t = a[*p]; 12: 13: t = t / a[i]; 14: 15: if (t == 2) 16: assert (i == 1); 17: else 18: assert (i == 3); 19: } (i >= 4) a[*p] a[i] (t == 2) (i == 1) (i == 3)

  32. Questions

More Related