├── .gitignore
└── published
├── CVE-2019-9901-path-traversal.md
├── images
└── owasp-xss.png
├── javascript-security-cheat-sheet.md
├── mean_io-review.md
├── owasp_top_10_for_js_-_xss.md
├── safenuget.md
└── the_problem_with_jsonp.md
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eoftedal/writings/99249e9b42a93728954fe22cf1d9e5c488cfa8ed/.gitignore
--------------------------------------------------------------------------------
/published/CVE-2019-9901-path-traversal.md:
--------------------------------------------------------------------------------
1 | # CVE-2019-9901 - Istio/Envoy Path traversal
2 |
3 | TLDR; I found a path traversal bug in Istio's authorization policy enforcement.
4 |
5 | ## Discovery
6 |
7 | About a year ago, as a part of a customer project, I started looking at Istio, and I really liked what I saw.
8 | In fact I liked it so much that I decided to submit a talk for it for JavaZone in 2018.
9 | My favorite thing about Istio was, and still is, the mutualTLS authentication and authorization with workload bound certificates with SPIFFE identities.
10 |
11 | Istio has evolved a lot from the first version 0.5.0, which I initially looked at, to the 1.1 release. The 0.5.0 authorization policies came in the form of *deniers*, which sounded a lot like deny lists. The later versions have moved to a positive security model (allow list), where you can specify which workloads (and/or end-users based on JWT) should be allowed to access certain services. Further restrictions can be specified using a set of protocol based authorization rules. I really like the coarse-grained workload authorization, but I'm not too fond of the protocol based rules. We have seen different parsers interpreting the same thing in different ways way too many times. Some perfect examples of this, are in Orange Tsai brilliant research presented in A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages!. I mentioned my concerns about this in some later versions of my Istio talk, but never actually tested it... untill now...
12 |
13 | ## The bug
14 |
15 | I set up a simple project with a web server and deployed it on Kubernetes. The web application had two endpoints `/public/` and `/secret/`. I added an authorization policy which tried to grant access to anything below `/public/`:
16 |
17 | ```
18 | rules:
19 | - services: ["backend.fishy.svc.cluster.local"]
20 | methods: ["GET"]
21 | paths: ["/public/*"]
22 | ```
23 |
24 | I then used standard **path traversal** from curl:
25 |
26 | ```
27 | curl -vvvv --path-as-is "http://backend.fishy.svc.cluster.local:8081/public/../secret/"
28 | ```
29 | And was able to reach `/secret/`.
30 |
31 | ## Timeline
32 |
33 | The istio team was very friendly and responsive and kept me up to date on the progress.
34 |
35 | * 2019-02-18: I send the intial bug report sent to the istio-security-vulnerabilities mailbox
36 | * 2019-02-18: Istio Team acknowledges receiving the report
37 | * 2019-02-20: Istio Team reports the bug has been triaged and work started
38 | * 2019-02-27: I ask some follow up questions to the mail received on the 20th
39 | * 2019-02-27: Istio Team replies to questions
40 | * 2019-03-28: Istio Team updates me about working with the Envoy team to fix this and plan to release this on April 2nd. The envoy issue was created on the 20th of February: https://github.com/envoyproxy/envoy/issues/6008
41 | * 2019-04-01: Istio Team sends an new update setting April 5th as a new target date
42 | * 2019-04-05: The security fix is published in Istio version 1.1.2/1.0.7 and Envoy version 1.9.1. The Envoy bug is assigned CVE-2019-9901
43 |
44 |
--------------------------------------------------------------------------------
/published/images/owasp-xss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eoftedal/writings/99249e9b42a93728954fe22cf1d9e5c488cfa8ed/published/images/owasp-xss.png
--------------------------------------------------------------------------------
/published/javascript-security-cheat-sheet.md:
--------------------------------------------------------------------------------
1 | Single Page Web App Security Cheat Sheet
2 | ========================================
3 |
4 | This is intended as a simple abbreviated cheat sheet for securing JavaScript based single page web apps. It's not meant to cover everything in depth, but rather point you in the correct directions with resources.
5 |
6 | What happens in JS, stays in JS
7 | -------------------------------
8 |
9 | Or to be more precise: What happens in the browser, stays in the browser. We cannot make security decisions for our data within the browser. Any input validation (whether in html tags or implemented in JS) in the browser is purely cosmetic and for user guidance. Any security decisions based on data within the browser, need to be double checked on the server. Anything happening in the browser can be altered. An attacker can access your services directly, thus circumventing any security implemented in the browser. In Sverre H. Huseby's excellent book ["Innocent Code"](http://innocentcode.thathost.com/) this split between server and browser is referred to as the *Invisible security barrier*.
10 |
11 | *Rule: Access control, input validation and security decisions __must__ be made on the server.*
12 |
13 | Cover your XSS
14 | --------------
15 |
16 | Cross site scripting is a serious vulnerability. Even though XSS is often demonstrated using simple alert boxes, XSS is a common vector for delivering exploits. Consider using XSS to add an applet tag pointing to a malicious Java application. Game over (because I know you forgot to update to the latest Java).
17 |
18 | We need to escape untrusted data whenever we are outputting data in our templates. And we need our escaping to [be aware](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet) [of context](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet).
19 |
20 | Whenever we are building code from strings (`eval`, `new Function`, `setTimeout`, `setInterval`), we need to be really careful. Escaping quickly becomes _very_ difficult, so it's better to just avoid it. [JSHint](http://www.jshint.com/) says "eval is evil", and I agree.
21 |
22 | Untrusted data can come from [so many places](http://code.google.com/p/domxsswiki/wiki/Sources). Some examples are URIs, JSON services, `window.referrer`, `window.name`, input fields, cookies. And there are [lots of sinks](http://erlend.oftedal.no/blog/?blogid=127) that output raw HTML into the DOM, and can thus result in JS execution.
23 |
24 | *Rule: Handle untrusted data with care — use contextual encoding and avoid building code from strings.*
25 |
26 | You have been served
27 | --------------------
28 |
29 | In a single page web app, private data only exists in the app's JSON services, thus it goes without saying we need to protect these services. We need to make sure [authentication](http://erlend.oftedal.no/blog/?blogid=128) and [authorization](http://erlend.oftedal.no/blog/?blogid=133) (access control) is properly implemented. We need to make sure we treat incoming data correctly — taking into account character sets, content-type, input validation. We need to make sure we don't expose unexpected data (e.g. a user's password hash). And we need to avoid [mass assigment](http://erlend.oftedal.no/blog/?blogid=129) — allowing an attacker to change fields we don't expect to be changed. We need to avoid things like [CSRF](http://erlend.oftedal.no/blog/?blogid=130).
30 |
31 | *Rule: Protect your services*
32 |
33 | Head's up
34 | ---------
35 |
36 | Browsers these days support a number of HTTP headers we can use to protect our app. These include `X-Frame-Options` to avoid [Clickjacking](http://www.sectheory.com/clickjacking.htm), [Content Security Policy](https://developer.mozilla.org/en-US/docs/Security/CSP) to mitigate Cross Site Scripting and related attacks, [`X-Content-Type-Options`](http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx) to make sure the browser cannot be tricked into for instance [interpreting JSON as HTML](http://erlend.oftedal.no/blog/research/json/testbench.html) (only works in some browsers).
37 |
38 | *Rule: Learn how to use security HTTP headers*
39 |
40 | Resources
41 | ---------
42 |
43 | * [OWASP Top 10 for JavaScript](http://erlend.oftedal.no/blog/?blogid=125)
44 | * [DOM XSS Wiki](http://code.google.com/p/domxsswiki/wiki/Sources)
45 | * [DOM Based XSS Prevention Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
46 | * [XSS (Cross Site Scripting) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet)
47 | * [Content Security Policy](https://developer.mozilla.org/en-US/docs/Security/CSP)
48 | * [Clickjacking](http://www.sectheory.com/clickjacking.htm)
49 |
50 | Want to Contribute?
51 | -------------------
52 |
53 | Got ideas for improving this cheat sheet? Send me an [email](mailto:erlend@oftedal.no) or send me a pull request. Contributions will be attributed.
54 |
55 | Authors
56 | -------
57 | Erlend Oftedal - [@webtonull](https://twitter.com/webtonull) / [eoftedal](https://github.com/eoftedal)
58 |
59 |
--------------------------------------------------------------------------------
/published/mean_io-review.md:
--------------------------------------------------------------------------------
1 | Mean IO security review
2 | =======================
3 |
4 | I've been meaning to review Mean IO for some time and finally found the time to take a quick look at it
5 |
6 | Password handling
7 | -----------------
8 | I was really happy to see to see that Mean IO is using pbkdf/2 for password hashing before storing it. It's using a 16 byte salt created using crypto.randomBytes and it's using 10000 rounds with a keylength of 64 bytes.
9 |
10 | The password policy is however pretty weak. The only requirement is that passwords are between 8 and 20 characters. There are no character set requirements (upper, lower, numeric, special) and the maximum length of 20 is very odd. Why set such a low maximum length. The storage size is the same for 8 character and 100 character password after hashing.
11 |
12 | Also there is no rate limiting or account lockout on password guessing. An external attacker can guess as many times he/she wants for the same account without getting stopped by temporary accounts lockout after a given number of tries or a captcha.
13 |
14 |
15 | Cross Site Scripting (XSS)
16 | --------------------------
17 | While the templates seem to use proper escaping for most cases, there is a Cross Site Scripting vulnerability in the user's `name` field. This appears after registering a user with a username of `` You can test that one [here](http://www.insecurelabs.org/Search.aspx?query=%22%3E%3Cscript%3Ealert%281%29%3C/script%3E). In reflected XSS, the attacker has to trick the user into opening the URL somehow - typically by employing iframes, phishing or shortened URLs.
8 |
9 | In stored, or persistent, XSS, the attacker is able to store the attack string in the database. Since the attack is not dependent on the exact URL being visited anymore, the attacker can simply wait for a victim to visit the otherwise legit page. An example could be the commenting section here: [http://www.insecurelabs.org/Talk/Details/5].
10 |
11 | # Twists on traditional XSS
12 | Single page webapps are usually loading a static HTML-layout, which is the exact same file for all users, and then data and private information is loaded using JSON services. If there is HTML-tags inside our JSON-data we would normally expect the browsers not to render this content, but rather treat application/json as, well, JSON. However this is not always the case. Some browser, and especially IE, tends to try to second guess the content-type given by the server. This is called content-sniffing, and is in place because at some point in time servers tended not to send the correct content-type, and thus browsers could help the developers and end user by checking "what the content really was".
13 |
14 | I built a small [test bed](http://erlend.oftedal.no/blog/research/json/testbench.html) for showing how this works. You will see a green check if the browser treats the content as HTML (and thus allows scripting). It is expected that this happens if we return the JSON with Content-Type `text/html`, but not with any of the others. Well maybe an empty Content-Type could be excused, but if the browser says `application/json, the browser should definitely not treat the contents as HTML.
15 |
16 | # DOM-based XSS
17 | It's expected that DOM-based XSS will be more commons in apps reying heavily on JavaScript, than what has been seen in traditional apps. DOM-based XSS occurs because user input is unsafely handled in javascript running on the page. We will address a few examples on this type of XSS. Some of these attacks never reach the server side, and thus cannot be detected by server side code.
18 |
19 | ## Insecure writes
20 |
21 | Insecure writes happens when user input is written to the DOM without first being sanitized. Data can come in through user input in the browser, or it can be loaded through JSON from the server (which would mean it was a stored DOM-based XSS attack). Insecure writes means we are either outputting the data directly in the DOM using `.innerHTML` or through unsafe jQuery functions like:
22 |
23 | $.after()
24 | $.append()
25 | $.appendTo()
26 | $.before()
27 | $.html()
28 | $.insertAfter()
29 | $.insertBefore()
30 | $.prepend()
31 | $.prependTo()
32 | $.replaceAll()
33 | $.replaceWith()
34 | $.unwrap()
35 | $.wrap()
36 | $.wrapAll()
37 | $.wrapInner()
38 | $.prepend()
39 |
40 | ## Insecure code execution
41 |
42 | As mentioned in [A1 - Injection](http://open.bekk.no/owasp-top-10-for-javascript-a1-injection/) the use of insecure functions in JavaScript can cause insecure code execution. More specifically this means using functions that build JavaScript from strings:
43 |
44 | eval(string)
45 | new Function(string)
46 | setTimeout(string, time)
47 | setInterval(string, time)
48 |
49 | In addition to these we find API specific functions like `$.globalEval(string). As we can easily imagine dynamically building code containing user input is probably not a good idea, and is very likely to lead to problems down the road. JSHint, which is a common tool for quality checks on JavaScript, agrees: eval is evil.
50 |
51 | ## Insecure use of APIs
52 |
53 | Insecure use of jQuery can also lead to unexpected XSS. As mentioned in jQuery XSS something as simple as this can lead to XSS: `$(location.hash)`
54 |
55 | This can be exploited with:
56 |
57 | http://example.com/some/page#
58 |
59 | The next one is a bit more subtle (courtesy of [An overview of DOM XSS](http://sec.omar.li/2012/05/overview-of-dom-xss.html)):
60 |
61 | hash = location.hash.substring(1);
62 | if (!$('a[name|="' + hash + '"]')[0]) {
63 | // not important
64 | }
65 |
66 | An input of `"]
` would actually work here.
67 |
68 | While the examples above jQuery specific, it is very likely that there are similar problems in other frameworks.
69 |
70 | ## Insecure use of document.location
71 |
72 | Allowing user input to be directly assigned to document.location`, can easily lead to XSS in the form of `javascript:` URLs. The following example is from twitter back in september 2010 (I _highly_ recommend you read the full blog post here: [Minded Security Blog: A Twitter DomXss, a wrong fix and something more](http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html)):
73 |
74 | (function(g){var a=location.href.split("#!")[1];if(a){g.location=g.HBR=a;}})(window);
75 |
76 | The code above, extracts whatever comes after `#!` in the url, and asigns it to `window.location`. The intention was to allow a url of `http://twitter.com/#!/webtonull` to be redirected to `http://twitter.com/webtonull`. However consider the following url:
77 |
78 | http://twitter.com/#!javascript:alert(1)
79 |
80 | ## Persistent client side XSS
81 |
82 | If the XSS vector is persisted in Web Storage, and later rendered in an insecure way, we call it a persistent client side XSS. As the name implies this attack will never reach the server, but still trigger every time the vulnerable page is loaded in the given browser.
83 |
84 | # XSS when using templates
85 | Templating from frameworks like Mustache.js and underscore.js etc. allow javascript frameworks to clearly seperate view from data. They normally provide a set of tags for allowing coding and data output. The set from underscore.js looks like:
86 |
87 | `<% %>` - view logic (JavaScript code)
88 | `<%= %>` - data output (no escaping)
89 | `<%- %>` - data output (HTML escaping)
90 |
91 | The HTML escaping escapes `&`, `<`, `>`, `"`, `'` and `/`. I don't intend to pick on underscore.js. This is one of the better escaping functions I've seen. But we need to remember to use the HTML escaping tag. And there are contexts where this will not work, simply because HTML escaping is not the correct escaping.
92 |
93 | **Quoteless HTML attributes**
94 |
95 | Template code:
96 |
97 |
...>
98 |
99 | Attack:
100 |
101 |
102 |
103 | **HTML comments** - courtesy of http://html5sec.org/#133
104 |
105 | Template code:
106 |
107 |
108 |
109 | Attack:
110 |
111 |
112 |
113 | **Inside script tags**, but you are not using those in a javascript app, right?
114 |
115 | Template code:
116 |
117 |
120 |
121 | Attack:
122 |
123 |
126 |
127 | **Inside javascript event handlers**, but you are not using those in a javascript app, right?
128 |
129 | Template code:
130 |
131 |
132 |
133 | Attack:
134 |
135 |
136 |
137 | **Insecure use of URLs**
138 |
139 | Template code:
140 |
141 |
142 |
143 | Attack:
144 |
145 |
146 |
147 | The above list is not complete. There are a lot more weird contexts. See [http://html5sec.org/] and the OWASP cheat sheets listed below.
148 |
149 | # Third-party javascript
150 | When you are adding direct links to third-party javascript files, instead of putting the files locally on your server, you have to remember that you are now allowing XSS from the domain hosting that file. That's regardless of whether you are loading a javascript library or "just" using JSONP to load data. Consider a `
153 |
154 | Now if example.com goes rougue or is hacked, example.js could start delivering malware to your users or silently stealing their credentials when they log in.
155 |
156 | Another thing to consider any security vulnerabilities in downloaded libraries. When you are pulling in some third party script, you should also make sure you later stay up to date, and follow any announcements from the developers of that library.
157 |
158 | # Mitigation
159 | * **Default to secure methods** - use `$.text()` instead of `$.html()`
160 | * **Default to escaping output** - use `<%- %>` instead of `<%= %>`
161 | * **Check your templating framework's escaping code** - is it as thorough as underscore.js or does it escape fewer characters?
162 | * **Prefer frameworks with secure defaults**
163 | * **Set the correct Content-Types and use proper JSON escaping**
164 | * **Beware of XSS contexts** - make sure you are not using the wrong/insufficient escaping for the contexts
165 | * **Avoid sticking user data in insecure functions like `eval`**
166 | * **Beware when using user data with APIs like jQuery** - test it
167 | * **Use automated tests with XSS attacks** - test your code and templates using automated javascript tests and bad data
168 | * **Read and learn the OWASP XSS cheat sheets by heart**
169 | * **Use [jQuery encoder](https://github.com/chrisisbeef/jquery-encoder) for complex contexts**
170 |
171 | # Resources
172 |
173 | * [OWASP XSS Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet)
174 | * [OWASP Abridged XSS Prevention Cheat Sheet](https://www.owasp.org/index.php/Abridged_XSS_Prevention_Cheat_Sheet)
175 | * [OWASP DOM-Based XSS Prevention Cheat Sheet](https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet)
176 | * [An overview of DOM XSS](http://sec.omar.li/2012/05/overview-of-dom-xss.html)
177 | * [jQuery XSS](http://ma.la/jquery_xss/)
178 | * [HTML5 Security Cheatsheet](http://html5sec.org/)
179 | * [jQuery encoder](https://github.com/chrisisbeef/jquery-encoder)
180 |
181 | # Missing anything?
182 | Contact me on [twitter](https://twitter.com/webtonull) or add a comment below, and I'll be happy to add (with attribution).
183 |
--------------------------------------------------------------------------------
/published/safenuget.md:
--------------------------------------------------------------------------------
1 | NuGet developer: Help me help you
2 | =================================
3 |
4 | Are you a developing NuGet packages? Good. Me too. We developers all make mistakes from time to time. And the problem is, some of those mistakes become vulnerabilities. Now the problem is, how will the users of your library know?
5 |
6 | Using libraries with known vulnerabilities is a big problem. So big that it has in fact made it to the newly published [OWASP Top 10 2013](https://www.owasp.org/index.php/Top_10#OWASP_Top_10_for_2013). It's under *A9 Using Known Vulnerable Components*.
7 |
8 | How can you help?
9 | -----------------
10 | Help me help you, or rather help me help your package's users. I have created a NuGet pacakge called [SafeNuGet](https://github.com/eoftedal/SafeNuGet). After installing this package into a project, SafeNuGet will check the status of the references libraries on every build, and warn the developers if anything is found to be vulnerable. However the status of the libraries need to be maintained. This is wher you come in. We help the users of our libraries by maintaining a [a list of vulnerable versions of our packages](https://github.com/eoftedal/SafeNuGet/blob/master/feed/unsafepackages.xml). And in the true spirit of Open Source, everything is free.
11 |
12 | So how do you submit your list of vulnerable versions? You can either [register an issue](https://github.com/eoftedal/SafeNuGet/issues), create a [pull request](https://github.com/eoftedal/SafeNuGet) or send me an email at [erlend@oftedal.no](mailto:erlend@oftedal.no). Please include the package id, the versions affected and a URL for more information.
13 |
14 | Thank you for helping out.
15 |
16 | Code contributions
17 | -------------------
18 | If you want to help improve SafeNuGet itself as well, you are more than welcome to. Pull requests are more than welcome, and so are suggested enhancements through github's issue tracker.
19 |
20 | Like the idea?
21 | --------------
22 | Help me spread the word, by telling your fellow NuGetters.
23 |
24 |
--------------------------------------------------------------------------------
/published/the_problem_with_jsonp.md:
--------------------------------------------------------------------------------
1 | # Why JSONP is a bad idea
2 |
3 | A friend asked me to recap why JSONP is a bad idea. This is my response.
4 |
5 | ## Why JSONP?
6 |
7 | JSONP was invented before CORS was available in browsers, as a means to load data cross site. The JSONP endpoint would
8 | support a callback parameter and the response would be wrapper in this callback:
9 |
10 | HTML on domain-a.com:
11 |
12 | ````
13 |
18 |