LECTURE 22: SECURE CODING BASICS
CSE 442 – Software Engineering
LECTURE 22: SECURE CODING BASICS CSE 442 Software Engineering - - PowerPoint PPT Presentation
LECTURE 22: SECURE CODING BASICS CSE 442 Software Engineering Lessons Already Learned Hackers take advantage of any opening provided But most also lazy (talk to struggling 115/116 student) Any easy success in breaking code encourages
LECTURE 22: SECURE CODING BASICS
CSE 442 – Software Engineering
¨ Hackers take advantage of any opening provided
¤ But most also lazy (talk to struggling 115/116 student) ¤ Any easy success in breaking code encourages them
¨ Copy-and-pasting easy but who executes user input?
Lessons Already Learned
Stupidity Never Stops
Stupidity Never Stops
Stupidity Never Stops
Stupidity Never Stops
Stupidity Never Stops
Stupidity Never Stops
Human Nature: 1 Humanity: 0
¨ Also need to remember some people are just jerks
Hackers always win when it becomes a game
Security Key Concept
Web Applications
¨ Increasingly common software, even in industry ¨ Requires very different coding approach
¤ Should improve over time, but still new ¤ Distribution methods make security holes easier to find ¤ Over 70% of web apps had at least 1 security flaw
Javascript
¨ Javascript can be force for good and evil ¨ Improves interactivity & enables good UI/UX ¨ Also means many security exploits opened ¨ Very open language with many ways to integrate
¤ Foreshadowing alert: creates big problem later
¨ Includes hooks to respond to lots of page events
Hypertext Transfer Protocol
¨ Primary application layer protocol for web apps ¨ HTTP not encrypted; HTTPS is more secure version
¤ Browser encrypts/decrypts traffic with web server
¨ Both standards define stateless protocol
¤ Each request & response full interaction for protocol ¤ Connection info not retained by sender or receiver
¨ Stateless protocol good if only serving static page
¤ But this became problem once applications served ¤ Drove storing session data parallel to using protocol
GET vs. POST
¨ Two ways to send data from page to server
¤ GET default approach; must specify when POST wanted
¨ GET uses URI with data embedded after link
¤ Data included as name-value pairs after ?
¨ POST sends data along page request
¤ Still readable, but harder since not included in URI
GET POST
Cookies
¨ Small pieces of data that provide interaction state
¤ Each cookie stored as text on user's computer ¤ Set & retrieved when requested by server (or Javascript)
¨ Set of information defined by each cookie
¤ Name: unique string to identify it ¤ Value: stored data set by server ¤ Attributes: More name-value pairs
for holding other information (optional)
Cookie Types
Deleted when browser closes
Session cookie
Eventually expires
site each visit
Persistent cookie
HTTPS
Secure cookie
domain other than main site
Third-party cookie
by Javascript
HTTPOnly cookie
supported in all browsers
SameSite cookie
Cookie Scope
¨ Domain attribute sets which servers can use cookie
¤ Page on www-student.cse.buffalo.edu could specify
Domain=.buffalo.edu & then usable by all UB servers Domain=.cse.buffalo.edu for departmental servers Domain=www-student.cse.buffalo.edu for itself
¨ Path attribute adds restrictions to paths on server
¤ Path=/team01 limits to pages in folders:
/team01, /team01/fac, /team01/fac/hertz, etc.
¤ Path=/team01/fac not usable if page just in /team01
Viewing/Managing cookies
¨ Chrome: use URI chrome://settings/
content/cookies
¨ Firefox: Select menu Item
Tools/Web Developer/Storage Inspector
¨ MS Edge: Select menu item
Developer tools & then open Debugger tab
Benefits of Cookies Authentication Session Management Personalization Tracking
Benefits of Cookies Authentication Session Management Personalization Tracking
Persistent Authentication
¨ PHP already includes support for browser cookies
¤ Stores client data that can be used to track a user ¤ May not be accepted; should include tests to be certain ¤ Cookies not secure; many attack vectors possible
¨ Cookies sent within HTTP[S] header during request
¤ setcookie() directs creation of cookie by PHP code ¤ Can also check if cookie already exists using isset() ¤ setcookie() also deletes cookie, but requires trick
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
isset - Returns true if cookie already exists $COOKIE[] - Site's cookies read via assoc array "SSID" – Specifies the name of cookie to read
retrieve_ssid_from_db - "Retrieves" "correct" SSID
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
header - Built-in function issues browser redirect 'Location: - Required text for this function test.edu/login.php – target URI to load
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <html>
setcookie - PHP's built-in function which creates, updates, & deletes cookie Must appear BEFORE <HTML> tag
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
"SSID" "shoeSize" – Name of cookie is first argument "deleted"
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
"Bob" "12" - Value of cookie is second argument; "" using "" theoretically deletes cookie
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
".cse.buffalo.edu" - Sets domain attribute "/CSE442-542" - Path attribute also optional
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
Third argument specifies time cookie will expire
Persistent Cookie Example
<?php if( (!isset($_COOKIE["SSID"])) || ($_COOKIE["SSID"] != retrieve_ssid_from_db($username) ) { header('Location: test.edu/login.php'); } else { setcookie("SSID", "Bob", time()+60, ".cse.buffalo.edu", "/CSE442-542", 1); setcookie("shoeSize", "12"); setcookie("deleted", "", time()-3600); } ?> <HTML>
1 in last argument limits use to HTTPS requests
Script Kiddie Hacking
Script Kiddie Hacking
Misconfiguration
¨ System uses outdated server or 3rd party software ¨ Unpatched programming language (JSP, Java, PHP) ¨ Server not locked; leaves services, ports, APIs open ¨ Passwords unchanged or guessable for all to use
¤ Application has well known password for admin account ¤ Database exposed & allows users to subvert security
Not secured; Hack me!
Script Kiddie Hacking
Source Code Visibility
¨ Traditional app sent as machine-language
¤ No source code to hunt for weaknesses ¤ Most users lack skills to decompile
¨ Client-side code sent by web apps
¤ Client execution uses JS, HTML, & CSS ¤ Needs source code for greatest support ¤ Users will find & exploit weaknesses ¤ Even modify source with little effort ¤ Web app security must reside on server
Script Kiddie Hacking
Client Side – Javascript
¨ Cannot rely on Javascript checks for security either
function checkRole(role r) { if (r == admin){ return 1; } return 0; }
¨ Name changes insufficient; context all hacker needs ¨ Javascript code modified by client before running ¨ Using debugger, could change value of variables
Client Side – Hidden fields
¨ Page relies on field having data, but field hidden
¤ Often done within form so sent as part of submission
<input type=“hidden” name=“role” value=“admin”>
¨ Feels secure since user cannot see or edit field
¤ But easy to see by client, since included in HTML code ¤ Using Web Developer mode, client can easily to modify ¤ Still creates game between developer and hacker
Client Side – Cookies (1)
¨ Common flaw: using cookie to establish security role
¤ Web pages could include code to determine if cookie set
if (username == “Admin”) { document.cookie =”role=admin"; } else { document.cookie =”role=guest"; }
¤ Even without code, cookies still visible to users
¨ Only matter of time until someone finds admin role
¤ Hackers have more time; you will always lose game ¤ Even when role worthless, challenge drives hackers
Client Side – Cookies (2)
¨ Common flaw: using cookie to establish security role
¤ Even if server executes code will still have weakness
<?php if(isset($_COOKIE["SSID"])) && $_COOKIE["ROLE"] == "%&d3dBD") { // Output admin view of page } else { // Output normal view of page } ?>
¨ Client machine stores cookies so users can modify
Hackers always win when it becomes a game
Security Key Concept
Script Kiddie Hacking
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Login: mhertz ****** Password:
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Login: mhertz ****** Password:
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
String q = "SELECT * FROM useraccounts" + "WHERE account = ?"; PreparedStatement st=conn.prepareStatement(q,??); st.setString(1, uri.getFolder("1")); ResultSet results = st.executeQuery( );
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
String q = "SELECT * FROM useraccounts" + "WHERE account = ?"; PreparedStatement st=conn.prepareStatement(q,??); st.setString(1, uri.getFolder("1")); ResultSet results = st.executeQuery( );
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
¤ GET request cannot be trusted without verification
String q = "SELECT * FROM useraccounts" + "WHERE account = ?"; PreparedStatement st=conn.prepareStatement(q,??); st.setString(1, uri.getParam("acct")); ResultSet results = st.executeQuery( ); http://example.edu/app/accountInfo?acct=admin
Direct Object References
¨ Client’s authorization sets objects & info provided
¤ Easy edits on client’s machine cannot subvert security ¤ But anyone can access data using properly built request
¨ Client unreliable; server must keep client’s state
¤ GET request cannot be trusted without verification ¤ Also will be problem if POST or cookie only data source
Script Kiddie Hacking
Authentication Errors (1)
Authentication Errors (2)
Authentication Errors (3)
PHP to Require HTTPS Usage <?php if( (!isset($_SERVER['HTTPS'])|| ($_SERVER['HTTPS']!='on')) { header('Location: '. 'https://'. $_SERVER['SERVER_NAME']. $_SERVER['PHP_SELF']); } ?>
Authentication Errors (3)
HTML supporting HTTP login <div id="login_form"> <!-- div avoids mistakenly submitting data --> User name: <input type="text" id="username"> Password: <input type="password" id="plaintext"> <input type="button" value="Login"
</div>
Authentication Errors (3)
JS supporting HTTP login // Using crypto-js & jQuery libraries var submit = function() { var name = $('#username').val(); var plaintext = $('#plaintext').val(); var cyphertext = CryptoJS.SHA3(plaintext); $.post("login.php", {username:name, passwd:cyphertext}, fnHandlingResult); };