Talk in Switzerland at European Broadcasting Union cyber security event - Feb 2017.
Discussing some core aspects of secure application development, technical security controls and secure systems development lifecycle....
2016 – in review
• 83,000 impacted by breach at Gyft Inc
• 63,000 records exposed at UCF (Florida)
• 15,000 credit cards Bailey's Inc.
• Hyatt data beach 250 hotels in 50 countries
• Neiman Marcus – 5,200 accounts
• TaxSlayer – 8,800 customers
• Yahoo – 500,000,000 accounts
Globally, every second, 18 adults
become victims of cybercrime
- Symantec
“The loss of industrial information and intellectual property
through cyber espionage constitutes the greatest transfer of
wealth in history” - Keith Alexander
“One hundred
BILLION
dollars” -
Dr Evil
Eoin, I didn’t click it – My
Mum
Two weeks of ethical
hacking
Ten man-years of
development
Make this more difficult: Lets change the application code once a month.
Secure Development…
Requirements
and use cases
Design Test plans
Code
Test
results
Field
feedback
Security
requirements
Risk
analysis
Risk-based
security tests
Static
analysis
(tools)
Penetration
testing
Design
Review
Iterative approach
Code
Review
GPDR EU directive:
The General Data Protection Regulation (GDPR) (Regulation (EU) 2016/679)
is a Regulation by which the European Commission intends to strengthen
and unify data protection for individuals within the European Union (EU).
• a fine up to 20,000,000 EUR or up to 4% of the annual worldwide
turnover of the preceding financial year in case of an enterprise,
whichever is greater (Article 83, Paragraph 5 & 6[16])
Box ticking
So….
• What are we protecting against?
• Which security bugs do we spend time
fixing first?
• Continuous security
• Start early (design securely)
Lets Dig a Little Deeper……..
Some Stats
Based on 1000’s of continuous assessments using edgescan.com
Both Host, WebServer and Web application assessed.
Oldest Critical Vulnerabilities
Oldest “Known” vulnerability discovered in 2016 by edgescan;
CVE-2007-6420 - Cross-site request forgery (CSRF)
CVE-2007-3847 - Apache 2.3.0 DoS
CVE-2007-5000 - Apache HTTP Server XSS
CVE-2007-6388 - Apache HTTP Server XSS
9 year old vulnerabilities exist in the wild on live servers. Poor/Non existent patching is
the major root cause.
Good News is the frequency of occurrence is between 1.5% and 3%
What else happened in 2007?
First iPhone was launched…
GET vs POST HTTP Request
GET /search.jsp?name=blah&type=1
HTTP/1.0
User-Agent: Mozilla/4.0
Host: www.mywebsite.com
Referrer:
www.jimslamps.com/login?user=jim
&pass=w0rDup
Cookie:
SESSIONID=2KDSU72H9GSA289
<CRLF>
GET request POST request
POST /search.jsp HTTP/1.0
User-Agent: Mozilla/4.0
Host: www.mywebsite.com
Content-Length: 16
Cookie:
SESSIONID=2KDSU72H9GSA289
<CRLF>
name=blah&type=1
<CRLF>
GET request
GET /search.jsp?name=blah&type=1 HTTP/1.0
User-Agent: Mozilla/4.0
Host: www.mywebsite.com
Cookie: SESSIONID=2KDSU72H9GSA289
<CRLF>
POST request
POST /search.jsp HTTP/1.0
User-Agent: Mozilla/4.0
Host: www.mywebsite.com
Content-Length: 16
Cookie: SESSIONID=2KDSU72H9GSA289
<CRLF>
name=blah&type=1
<CRLF>
GET requests:
Can be bookmarked
Logged in server
Browser History
Cached
Easier to attack*
POST requests:
Data in HTTP body
Not logged on server
What are HTTP Headers?
HTTP headers are components of the message header of HTTP
Requests and Responses
HTTP headers define different aspects of an HTTP transaction
HTTP headers are colon-separated name-value pairs in clear-text
string format, terminated by a carriage return (CR) and line feed
(LF) character sequence.
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Data Validation
21
Input that is not directly entered by the user is typically less prone to
validation
Attacks discussed in this section apply to external input from any
client-side source
Standard form input control
Read-only HTML form controls (drop down lists, radio buttons,
hidden fields, etc)
HTTP Cookie Values
HTTP Headers
Embedded URL parameters (e.g., in the GET request)
Data Validation
22
Known Bad
Known Good
Exact
Match
Data Validation is
typically done using
one of three basic
approaches
All input must be
properly validated on
the server (not the
client) to ensure that
malicious data is not
accepted and processed
by the application
Data is validated against a list of explicit known values
Application footprint or “application attack surface” defined
Provides the strongest level of protection against malicious data
Often not feasible when a large number of possible good values are
expected
May require code modification any time input values are changed or
updated
Exact Match Validation
23
Example: Acceptable input is yes or no
if ($input eq“yes” or $input eq “no”)
Exact Match Validation Example
24
Validates the variable gender against 2 known values (Java)
static boolean validateGender (String
gender) {
if (gender.equals (“Female“))
return true;
else if (gender.equals (“Male“))
return true;
else
return false;
}
Known Good Validation
25
Often called “white list” validation
Data is validated against a list of allowable characters
Typically implemented using regular expressions to match known good data
patterns
Data type cast/convert functions can be used to verify data conforms to a
certain data type (i.e. Int32)
Expected input character values must be clearly defined for each input
variable
Care must be taken if complex regular expressions are used
A common mistake is to forget to anchor the expression with ^ and $
Regular Expressions
28
Regular Expressions is a term used to refer to a pattern-matching
technology for processing text
Although there is no standards body governing the regular expression
language, Perl 5, by virtue of its popularity, has set the standard for
regular expression syntax
A Regular Expression itself is a string that represents a pattern,
encoded using the regular expression language and syntax
Data Validation Techniques
29
Validates against a regular expression representing the proper
expected data format (10 alphanumeric characters) (.NET)
using System.Text.RegularExpressions;
static bool validateUserFormat(String userName) {
bool isValid = false; //Fail by default
// Verify that the UserName is 1-10 character alphanumeric
isValid = Regex.IsMatch(userName, @"^[A-Za-z0-9]{10}$");
return isValid;
}
Often called “BlackList” validation
Data is validated against a list of characters that are deemed to be
dangerous or unacceptable
Useful for preventing specific characters from being accepted by the
application
Provides the weakest method of validation against malicious data
Susceptible to bypass using various forms of character encoding
Known Bad Validation
32
Example: Validating entry into generic text field
if ($input !~/[rtn><();+&%’”*|]/)
Known Bad Validation Example
33
Validates against a regular expression of known bad input strings
(.Net)
using System.Text.RegularExpressions;
static boolean checkMessage(string messageText){
bool isValid = false; //Fail by default
// Verify input doesn’t contain any < , >
isValid = !Regex.IsMatch(messageText, @"[><]");
return isValid;
}
Bounds Checking
34
All external input must also be properly validated to ensure
that excessively large input is rejected
Length checking: A maximum length check should be performed on
all incoming application data
Input that exceeds the appropriate length or size limits must
be rejected and not processed by the application
Size checking: A maximum size check should be performed on all
incoming data files
The following code reads a String from a file.
Because it uses the readLine() method, it will read an unbounded amount of
input until a <newline> (n) charter is read.
InputStream Input = inputfileFile.getInputStream(Entry);
Reader inpReader = new InputStreamReader(Input);
BufferedReader br = new BufferedReader(inpReader);
String line = br.readLine();
This could be taken advantage of and cause an OutOfMemoryException or to
consume a large amount of memory which shall affect performance and initiate
costly garbage collection routines.
Bounds Checking – Example
35
Unbounded Reading of a file
Bounds checking – File size
$upload = new Zend_File_Transfer();
// Limit the size of all files to be uploaded to 40000 bytes
$upload->addValidator('FilesSize', false, 40000);
// Limit the size of all files to be uploaded to maximum 4MB and mimimum 10kB
$upload->addValidator('FilesSize', false, array('min' => '10kB', 'max' => '4MB'));
PS
Oh, yes…..Validation needs to be performed on the server side.
Validation is also important on the client side and so is output
encoding…..More later.
<html>
<body>
<? php
print "Not found: " .urldecode($_SERVER["REQUEST_URI"]);
?>
</body>
</html>
Request: http://testsite.test/file_which_not_exist
Response: Not found: /file_which_not_exist
Response:
Not found: / (but with JavaScript code <script>alert("TEST");</script>)
Request: http://testsite.test/<script>alert("TEST");</script>
Anatomy of a XSS Attack (bad stuff)
XSS Defense by Data Type and Context
Data Type Context Defense
String HTML Body HTML Entity Encode
String HTML Attribute Minimal Attribute Encoding
String GET Parameter URL Encoding
String Untrusted URL URL Validation, avoid javascript:
URLs, Attribute encoding, safe
URL verification
String CSS Strict structural validation, CSS
Hex encoding, good design
HTML HTML Body HTML Validation (JSoup,
AntiSamy, HTML Sanitizer)
Any DOM DOM XSS Cheat Sheet
Untrusted JavaScript Any Sandboxing (Google Caja)
JSON Client Parse Time JSON.parse() or json2.js
Safe HTML Attributes include: align, alink, alt, bgcolor, border, cellpadding, cellspacing,
class, color, cols, colspan, coords, dir, face, height, hspace, ismap, lang, marginheight,
marginwidth, multiple, nohref, noresize, noshade, nowrap, ref, rel, rev, rows, rowspan,
scrolling, shape, span, summary, tabindex, title, usemap, valign, value, vlink, vspace, width
HTML Encoding:
Certain sets of characters mean something special in HTML. For instance ‘<’ is used to open and
HTML tag and ‘&’ is used to and the beginning of a sequence of characters to define special symbols
like the copy write symbol. (htmlentities in PHP)
HttpUtility.HtmlEncode(“<script>alert(‘&’);</script>”)
<script>alert('&');</script>
Attribute Encoding:
Attribute encoding replaces three characters that are not valid to use inside attribute values in
HTML. Those characters are ampersand ‘&’, less-than ‘<’, and quotation marks ‘”’
HttpUtility.HtmlAttributeEncode(“<script>alert(”&”);</script>”)
<script>alert("&");</script>
URL Encoding
URL encoding used when you have some data that you would like to pass in the URL and that data
contains some reserved or invalid characters (&/<space>) – (urlencode() in php)
HttpUtility.UrlEncode(“Some Special Information / That needs to be in the URL”)
Some+Special+Information+%2f+That+needs+to+be+in+the+URL
OR
Some%20Special%20Information%20%2f%20That%20needs%20to%20be%20in%20t
he%20URL
The Problem
Web Page built in Java JSP is vulnerable to XSS
The Solution
<input type="text" name="data" value="<%= Encode.forHtmlAttribute(dataValue) %>" />
<textarea name="text"><%= Encode.forHtmlContent(textValue) %>" />
<button
onclick="alert('<%= Encode.forJavaScriptAttribute(alertMsg) %>');">
click me
</button>
<script type="text/javascript”>
var msg = "<%= Encode.forJavaScriptBlock(message) %>”;
alert(msg);
</script>
OWASP Java Encoder Project
https://www.owasp.org/index.php/OWASP_Java_Encoder_Project
OWASP HTML Sanitizer Project
https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project
Solving Real World Problems with the OWASP
HTML Sanitizer Project
The Problem
Web Page is vulnerable to XSS because of untrusted HTML
The Solution
PolicyFactory policy = new HtmlPolicyBuilder()
.allowElements("a")
.allowUrlProtocols("https")
.allowAttributes("href").onElements("a")
.requireRelNofollowOnLinks()
.build();
String safeHTML = policy.sanitize(untrustedHTML);
OWASP JSON Sanitizer Project
https://www.owasp.org/index.php/OWASP_JSON_Sanitizer
• Given JSON-like content, converts it to valid JSON.
• This can be attached at either end of a data-
pipeline to help satisfy Postel's principle: Be
conservative in what you do, be liberal in what you
accept from others.
• Applied to JSON-like content from others, it will
produce well-formed JSON that should satisfy any
parser you use.
• Applied to your output before you send, it will
coerce minor mistakes in encoding and make it
easier to embed your JSON in HTML and XML.
Solving Real World Problems with the OWASP
JSON Sanitizer Project
The Problem
Web Page is vulnerable to XSS because of parsing of untrusted JSON incorrectly
The Solution
JSON Sanitizer can help with two use cases.
1) Sanitizing untrusted JSON on the server that is submitted from the browser in
standard AJAX communication
2) Sanitizing potentially untrusted JSON server-side before sending it to the browser.
The output is a valid Javascript expression, so can be parsed by Javascript's eval
or by JSON.parse.
SAFE use of JQuery
$(‘#element’).text(UNTRUSTED DATA);
UNSAFE use of JQuery
$(‘#element’).html(UNTRUSTED DATA);
jQuery methods that directly update DOM or can execute
JavaScript
$() or jQuery() .attr()
.add() .css()
.after() .html()
.animate() .insertAfter()
.append() .insertBefore()
.appendTo()
Dangerous jQuery 1.7.2 Data Types
CSS Some Attribute Settings
HTML URL (Potential Redirect)
jQuery methods that accept URLs to potentially unsafe content
jQuery.ajax() jQuery.post()
jQuery.get() load()
jQuery.getScript()
Select * from user where username='uid' and password = 'password‘
uid = “EoinKeary”
password = “Password123!”
Select * from user where username=‘EoinKeary ' and password = ‘Password123!’
uid = “EoinKeary”
Password = “’ OR 1=1;--”
Select * from user where username ='EoinKeary' and password = ‘’ OR 1=1;--’
Anatomy of a SQL Injection Attack
public void bad(HttpServletRequest request, HttpServletResponse response) throws Throwable
{
String data;
Logger log_bad = Logger.getLogger("local-logger");
/* read parameter from request */
data = request.getParameter("name");
Logger log2 = Logger.getLogger("local-logger");
Connection conn_tmp2 = null;
Statement sqlstatement = null;
ResultSet sqlrs = null;
try {
conn_tmp2 = IO.getDBConnection();
sqlstatement = conn_tmp2.createStatement();
/* take user input and place into dynamic sql query */
sqlrs = sqlstatement.executeQuery("select * from users where name='"+data+"'");
IO.writeString(sqlrs.toString());
}
catch(SQLException se)
{
Exploit is executed (Sink)
Input from request (Source)
Anatomy of a SQL Injection Attack
String Building to
Call Stored Procedures
String building can be done when calling stored procedures as well
sql = “GetCustInfo @LastName=“ +
request.getParameter(“LastName”);
Stored Procedure Code
CREATE PROCEDURE GetCustInfo (@LastName VARCHAR(100))
AS
exec(‘SELECT * FROM CUSTOMER WHERE LNAME=‘’’ + @LastName + ‘’’’)
GO (Wrapped Dynamic SQL)
What’s the issue here…………
If blah’ OR ‘1’=‘1 is passed in as the LastName value, the entire table will be
returned
Remember Stored procedures need to be implemented safely. 'Implemented
safely' means the stored procedure does not include any unsafe dynamic SQL
generation.
Anatomy of a SQL Injection Attack
SQL Injection Attack Techniques
Boolean based blind SQL injection
par=1 AND ORD(MID((SQL query),
Nth char, 1)) > Bisection num—
UNION query (inband) SQL injection
par=1 UNION ALL SELECT query—
Batched queries SQL injection
par=1; SQL query;--
Commands to access Oracle Databases.
Many applications run an “admin” account
when using the database.
With SQL injection we can access the DB as an
admin user.
Total Control…
Query Parameterization (PHP)
$stmt = $dbh->prepare(”update users set
email=:new_email where id=:user_id”);
$stmt->bindParam(':new_email', $email);
$stmt->bindParam(':user_id', $id);
Query Parameterization (.NET)
SqlConnection objConnection = new
SqlConnection(_ConnectionString);
objConnection.Open();
SqlCommand objCommand = new SqlCommand(
"SELECT * FROM User WHERE Name = @Name
AND Password = @Password", objConnection);
objCommand.Parameters.Add("@Name",
NameTextBox.Text);
objCommand.Parameters.Add("@Password",
PassTextBox.Text);
SqlDataReader objReader =
objCommand.ExecuteReader();
Query Parameterization (Java)
String newName = request.getParameter("newName") ;
String id = request.getParameter("id");
//SQL
PreparedStatement pstmt = con.prepareStatement("UPDATE
EMPLOYEES SET NAME = ? WHERE ID = ?");
pstmt.setString(1, newName);
pstmt.setString(2, id);
//HQL
Query safeHQLQuery = session.createQuery("from
Employees where id=:empId");
safeHQLQuery.setParameter("empId", id);
Query Parameterization
(Cold Fusion)
<cfquery name="getFirst"
dataSource="cfsnippets">
SELECT * FROM #strDatabasePrefix#_courses
WHERE intCourseID = <cfqueryparam
value=#intCourseID#
CFSQLType="CF_SQL_INTEGER">
</cfquery>
Query Parameterization (PERL)
my $sql = "INSERT INTO foo (bar, baz) VALUES
( ?, ? )";
my $sth = $dbh->prepare( $sql );
$sth->execute( $bar, $baz );
Automatic Query Parameterization
(.NET linq4sql)
public bool login(string loginId, string shrPass) {
DataClassesDataContext db
= new DataClassesDataContext();
var validUsers = from user in db.USER_PROFILE
where user.LOGIN_ID == loginId
&& user.PASSWORDH == shrPass
select user;
if (validUsers.Count() > 0) return true;
return false;
};
Code Review - Find the Vulns!
<?php
$offset = $argv[0];
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn, $query);
?>
$offset is intended to be an Integer passed via a HTTP request.
How about this?
0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select
'crack', usesysid, 't','t','crack' from pg_shadow where usename='postgres'; --
Code Review - Find the Vulns!
<?php
$prod = $_GET[“prod"];
$query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>
Developer intends a product from a listbox control: E.g. TV, Radio, Bannana, Nail
Attacker:
Circumvents Listbox control and injects:
a%' exec master..xp_cmdshell 'net user test testpass /ADD‘ --
Resulting in :
"SELECT * FROM products WHERE id LIKE '%a%'exec master..xp_cmdshell 'net user test testpass
/ADD' --%'";
Command Injection
Web applications may use input parameters as arguments for OS scripts or
executables
Almost every application platform provides a mechanism to execute local
operating system commands from application code
Most operating systems support multiple commands to be executed from the
same command line. Multiple commands are typically separated with the pipe
“|” or ampersand “&” characters
Perl: system(), exec(), backquotes(``)
C/C++: system(), popen(), backquotes(``)
ASP: wscript.shell
Java: getRuntime.exec
MS-SQL Server: master..xp_cmdshell
PHP : include() require(), eval() ,shell_exec
md5("password") = 5f4dcc3b5aa765d61d8327deb882cf99
Sha1(“Password”)= 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
md5 and SHA1 are old and should not be used anymore.
Sha256(“password”)=
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
Sha256 = Stronger but still weak and easily broken using Rainbow Tables
Hashing
Salting
A salt is a random unique token stored with each password.
Let's say the salt is 5aP3v*4!1bN<x4i&3 and the hash
is 9537340ced96de413e8534b542f38089c65edff3.
Now your database of passwords is useless, because nobody has rainbow tables
that include that hash
Hash = h(password + salt)
It's computationally infeasible to generate rainbow tables for every possible salt.
So now we've forced the bad guys to start cracking the hashes again.
In this case, it'd be pretty easy to crack since I used a bad password, but it's still
better than him being able to look it up in a tenth of a second!
We need to add entrophy - Salting
Secure Password Storage, Java Example
public String hash(String password, String userSalt, int iterations)
throws EncryptionException {
byte[] bytes = null;
try {
MessageDigest digest = MessageDigest.getInstance(hashAlgorithm);
digest.reset();
digest.update(ESAPI.securityConfiguration().getMasterSalt());
digest.update(userSalt.getBytes(encoding));
digest.update(password.getBytes(encoding));
// rehash a number of times to help strengthen weak passwords
bytes = digest.digest();
for (int i = 0; i < iterations; i++) {
digest.reset(); bytes = digest.digest(salts + bytes + hash(i));
}
String encoded = ESAPI.encoder().encodeForBase64(bytes,false);
return encoded;
} catch (Exception ex) {
throw new EncryptionException("Internal error", "Error");
}
}
Standardized Algorithms for Password Storage
B/S Crypt
- Adaptive Hash
- Very Slow (work factor)
- Blowfish Derived
- Single Use Salt
Why scrypt over bcrypt?
- Much more secure than bcrypt
- Designed to defend against large scale hardware attacks
- There is a scrypt library for most major scripting
languages (Python, Ruby etc)
- CAUTION: New algorithm (2009)
- CAUTION: Scalability Problems
Forgot Password Secure Design
– Require identity and security questions
• Last name, account number, email, DOB
• Enforce lockout policy
• Ask one or more good security questions
– Send the user a randomly generated token via out-of-
band method
• email, SMS or token
– Verify code in same Web session
• Enforce lockout policy
– Change password
• Enforce password policy
Multi Factor
Authentication
• Passwords as a single authentication credential are
DEAD even for consumer services.
• Mobile devices as a “what you have” factor
• SMS and Native Mobile Apps for MFA
» not perfect but heavily reduce risk vs. passwords only
• Password strength and password policy less important
• You protect your magic user and fireball wand with MFA
• Protect your multi-billion dollar enterprise with MFA
MFA FTW
X-Frame-Options
HTTP Response Header
// to prevent all framing of this content
response.addHeader( "X-FRAME-OPTIONS", "DENY" );
// to allow framing of this content only by this site
response.addHeader( "X-FRAME-OPTIONS", "SAMEORIGIN" );
// to allow framing from a specific domain
response.addHeader( "X-FRAME-OPTIONS", "ALLOW-FROM X" );
Encryption in Transit HTTPS/TLS
• Sensitive data must be encrypted in transit via
HTTPS/SSL
• Starting when the login form is rendered
• Until logout is complete
• Confidentiality, Integrity and Authenticity
• OWASP HTTPS best
practices://www.owasp.org/index.php/Transport_Layer_P
rotection_Cheat_Sheet
• HSTS (Strict Transport Security) can help here
• Certificate Pinning can help here
Where are we going?
Dangerous Cookie Behavior
Attacking Sensitive Transactions
Real World Cross Site Request Forgery
Synchronizer Token Pattern
XSS Defense Criticality
Re-Authentication
Attacking Sensitive Transactions
Cross-Site Request Forgery (XSRF/CSRF)
Attacks the trust a web application has for authenticated users
Browser instances share cookies
Users typically browse multiple sites simultaneously
Attackers can abuse the shared cookie jar to send requests as the
authenticated user
Once authenticated, users are trusted throughout the lifetime of their
session
Applications do not require users to re-authenticate when executing
sensitive transactions
Anatomy of an CSRF Attack
This form will generate requests that resemble the following
GET http://www.example.com/Transfer.asp?acct=##&amount=##
Consider a consumer banking application that contains the
following form
<form action=“http://site.com/Transfer.asp” method=“POST” id=“form1”>
<p>Account Num: <input type=“text” name=“acct” value=“2345”/></p>
<p>Transfer Amt: <input type=“text” name=“amount” value=“10000”/></p>
</form>
<script>document.getElementById(“form1”).submit();</script>
What is the Result?
When the <img> tag loads, the attacker’s web site will send a request
to the consumer banking application
The user’s browser will attach the appropriate cookie to the attacker’s
forged request, thus “authenticating” it
The banking application will verify that the cookie is valid and process
the request
The attacker cannot see the resultant response from the forged
request
Does that matter?
Real World CSRF Attacks
Real-World CSRF attack hijacks DNS Server configuration of TP-Link routers
DNS altered to malicious server.
All request from router being re-routed to malicious sites. - 2014
PayPal Profile Hacking
Alter arbitrary peoples Paypal Profile via CSRF – 2016
135 Million ARRIS (Motorola) SURFboard modem
Unauthenticated reboot flaw via CSRF - 2016
CSRF within the Internal Network
CSRF allows external attackers to launch
attacks against internal applications! – Runs in Users Browser.
External web sites can trick your browser into making requests on
the internal network
Even easier against single-sign on
Effectively you are always logged into internal applications
All internal applications must be protected against CSRF
CSRF Defenses
Request that cause side effects should use the POST method
Alone, this is not sufficient
Validation of HTTP REFERER header (not recommended)
Tracking valid refererring pages may be problematic
Easy to spoof (but getting more difficult)
Require users to re-authenticate
Cryptographic Tokens
Synchronizer Token Pattern
“Hidden”
token in
HTML
Value defined by server when page is rendered. Value is stored in session.
Consider leveraging the java.security.SecureRandom class for Java
applications.
Upon Submit, token is sent with form.
Token value must match with value in session.
Attacker would not have token value. (XSS attack could get token is page
was vulnerable to XSS)
<form action="/transfer.do" method="post"> <input type="hidden" name="CSRFToken"
value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI
4MjJjZDE1ZDZjMTVi MGYwMGEwOA=="> … </form>
See also
https://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project
https://www.owasp.org/index.php/PHP_CSRF_Guard
https://www.owasp.org/index.php/.Net_CSRF_Guard
Challenge-Response
Challenge-Response is another defense option for CSRF
The following are some examples of challenge-response options.
CAPTCHA
Re-Authentication (password)
One-time Token
While challenge-response is a very strong defense to CSRF (assuming
proper implementation), it does impact user experience.
For applications in need of high security, tokens (transparent) and
challenge-response should be used on high risk functions.
Other CSRF Defenses
Require users
to re-
authenticate
Amazon.com does this *really* well
Double-cookie
submit
defense
Decent defense, but not based on randomness;
based on SOP
More high risk in app layer, but higher numbers in the network layer.
Talk about http basic authorization
Take a survey
User Controller Input = UCI
^ (Caret) Matches at the start of the string the regex pattern is applied to.
$ (dollar) Matches at the end of the string the regex pattern is applied to.
Set up a mask for certain types of fields
It’s very difficult to list all known bad input – harder to protect against potential future problems.
Note: The issue with $() is being worked on and will hopefully be much harder to exploit in jQuery 1.8
CREDIT THIS TO DAVE WICHERS.
Note: The issue with $() is being worked on and will hopefully be much harder to exploit in jQuery 1.8
75
76
77
78
79
EYCU Abritrary File Retrieval
Bcrypt is such a slow hashing algorithm. A speed comparison on a MacBook Pro with 2 Ghz Intel Core 2 Duo:
SHA-1: 118,600 hashes per second.
Bcrypt (with cost = 10): 7.7 hashes per second.
91
Sensitive data must be encrypted in transit via HTTPS/SSL
Starting when the login form is rendered
Until logout is complete
Confidentiality, Integrity and Authenticity
OWASP HTTPS best practices://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet
HSTS (Strict Transport Security) can help here
Certificate Pinning can help here