the art of identifying vulnerabilities - cascadiafest 2015
TRANSCRIPT
The Art of Identifying Vulnerabilities
CascadiaFest 2015
adam_baldwinevilpacket
The Art of Identifying Vulnerabilities
CascadiaFest 2015
What is a vulnerability?
Is it a bug?
A PROMISE THAT CAN BE
BROKEN
Systems knowledgeSecurity knowledgeCuriosity
To find vulnerabilities
SYSTEMS
Vulnerabilities grow in the cracks between
nuances & assumptions
You must understand the nuances of the systems you create and consume
https://www.youtube.com/watch?v=8aGhZQkoFbQ
What the heck is the event loop anyway?
JavaScript Nuanceshttp://dorey.github.io/JavaScript-Equality-Table/
http://nrn.io/view/javascript-common-pitfalls
http://youdontknowjs.com
JavaScript Nuances
db.passwd == user.passwd
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
If Type(x) is the same as Type(y), then If Type(x) is Undefined, return true. If Type(x) is Null, return true. If Type(x) is Number, then If x is NaN, return false. If y is NaN, return false. If x is the same Number value as y, return true. If x is +0 and y is −0, return true. If x is −0 and y is +0, return true. Return false. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false. Return true if x and y refer to the same object. Otherwise, return false. If x is null and y is undefined, return true. If x is undefined and y is null, return true. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y). If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y). If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y). If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y. Return false. NOTE 1 Given the above definition of equality:
String comparison can be forced by: "" + a == "" + b. Numeric comparison can be forced by: +a == +b. Boolean comparison can be forced by: !a == !b. NOTE 2 The equality operators maintain the following invariants:
A != B is equivalent to !(A == B). A == B is equivalent to B == A, except in the order of evaluation of A and B. NOTE 3 The equality operator is not always transitive. For example, there might be two distinct String objects, each representing the same String value; each String object would be considered equal to the String value by the == operator, but the two String objects would not be equal to each other. For Example:
new String("a") == "a" and "a" == new String("a")are both true. new String("a") == new String("a") is false. NOTE 4 Comparison of Strings uses a simple equality test on sequences of code unit values. There is no attempt to use the more complex, semantically oriented definitions of character or string equality and collating order defined in the Unicode specification. Therefore Strings values that are canonically equal according to the Unicode standard could test as unequal. In effect this algorithm assumes that both Strings are already in normalised form.
The Abstract Equality Comparison Algorithm
ಠ_ಠ
Vulnerabilities are prevalent between one
system & another
Whose code are you running in production?
Vulnerabilities multiply in the presence of
complexity
SECURITY
Let's put on our security hat
Where to start? Think like an attacker.
"The trust that happens without conscious decision, like a person sitting in a chair assuming someone hasn't removed one of the legs since they last sat in it."
- Jon Lamendola
"Thinking like an attacker means that we try to push the boundaries of useful things to see how we can get them to do something that it was not designed for."
- Matt Lowe
What promises does it make?
How does it make money?
OWASP Top 10
Broken auth & Session Management
Injection
Security Misconfiguration
Insecure Direct Object Reference
Cross-Site Scripting (XSS)
Missing Function Level Access Control
Sensitive Data Exposure
Unvalidated Redirects & Forwards
Using Known Vulnerable Components
Cross-Site Request Forgery
nodesecurity.io/advisories
https://github.com/paragonie/awesome-appsec
Learn from others
CURIOSITY
If you don't look, you won't find anything.
Act Ridiculous
How can it be used in other ways?
Ask questions, avoid statements
"A User would never..."
It's about what you don't know not what you know
DEMO
Understand the Code & Threat Model
Identify Inputs (Sources)
Identify Sinks
Follow the data Source -> Sink
Test & Validate
Repeat
tldr; Process
Understand the Code• "miliseconds conversion utility" • Simple JS without strict mode • Doesn't use any builtins (core functions) • It's intended to be used in the browser and
server side
FOLLOW THE DATASOURCE SINK
Identify Inputs (sources)• exports is one function • takes a value • Takes optional options argument
Identify data Sinks• Converted value is returned • regex is a sink that has known attacks
(regular expression denial of service)
1 var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
cat index.js | esgraph | dot -Tpng > out.png
1 var ms = require('./'); 2 var genstr = function (len, chr) { 3 var result = ""; 4 for (i=0; i<=len; i++) { 5 result = result + chr; 6 } 7 8 return result; 9 } 10 11 ms(genstr(process.argv[2], "5") + " minutea");
Test & Validate
Test & ValidateLength Run time (seconds)
10000 0.720
20000 2.491
30000 5.629
40000 12.386
Be okay with boring, monotonous and unfruitful testing Be persistent
</presentation>
adam_baldwinevilpacket