schwag09
Joined 13 years ago
Joined 13 years ago
I was also part of the team that audited RubyGems.org: https://github.com/trailofbits/publications/blob/master/revi...
Look at TOB-RGM-9 (an informational, largely out-of-scope finding) if you want to understand what could be done to mitigate some of these concerns. Nearly all of these gadget chains rely on Gem library functionality, which has this wonky .gemspec.rz metadata file that sits alongside the actual gem file. I understand that it'd be a challenging, backwards-incompatible change, but moving this file from Marshal to JSON would break a lot of these gadget chains. Perhaps there would be others, but it would raise the bar.
It looks for the following misconfigurations[0]:
- [ssrf] Server Side Request Forgery
- [http_splitting] HTTP Splitting
- [origins] Problems with referrer/origin validation
- [add_header_redefinition] Redefining of response headers by "add_header" directive
- [host_spoofing] Request's Host header forgery
- [valid_referers] none in valid_referers
- [add_header_multiline] Multiline response headers
- [alias_traversal] Path traversal via misconfigured alias
The alias traversal gotcha is one of the most pernicious I've seen. A single, seemingly innocuous '/' is the difference between a path traversal vulnerability or not.After a deeper dive I also noticed that my second statement about "batteries included" isn't totally true. Digging around in the Github repository I found a dozen or so heuristics here: https://github.com/facebook/mariana-trench/tree/main/configu.... It'll be cool to watch this fill out a bit.
From what I can tell by the documentation, it looks like Mariana's requires you to bring your own sources/sinks/sanitizers, so expect a lot of up front cost to integrate this into your toolchain. This as opposed to including commonly used rules or heuristics. Not a huge deal since users can write and share there own rules, but this looks like a framework for sophisticated static analysis and not a batteries included solution.
Maximizing utility on a website might look like dropping a user into a root REPL so they can perform arbitrary actions and are unlimited in their capabilities. Maximizing security might look like shutting down the website and all its associated servers. In reality, from a security perspective, we try to achieve a balance between the two by maximizing utility while minimizing security risk.
Personally, I think code as content, reflection, eval, etc move the slider too far in the utility direction. Of course this is a difficult problem to solve because nearly all our systems are built on the idea of code as content, which is also what makes it such a generalized vulnerability class.
Mixing code and content leads to all the most common injection-style vulnerability classes: buffer overflows, XSS, SQLi, command injection, etc. Fundamentally, I believe this is at the heart of the problem. The paper does go on to address this:
> Another proposed theory blames John von Neumann's stored program concept [15] for the woes of arbitrary code execution; the fact that data and program in computers are stored on the same storage medium may allow an attacker to illegitimately modify the program rather than the intended data [10].
From there it provides ROP as a counterpoint to the "stored-program hypothesis." This makes sense because ROP allows one to achieve arbitrary code execution without necessarily modifying the code. Although, while I agree that mixing code and content may not be the highest level abstraction for concern here, I do think it's often a fundamental flaw from a practical perspective.
'An American investment banker was at the pier of a small coastal Mexican village when a small boat with just one fisherman docked. Inside the small boat were several large yellowfin tuna. The American complimented the Mexican on the quality of his fish and asked how long it took to catch them.
The Mexican replied, “only a little while.”
The American then asked why didn’t he stay out longer and catch more fish?
The Mexican said he had enough to support his family’s immediate needs.
The American then asked, “but what do you do with the rest of your time?”
The Mexican fisherman said, “I sleep late, fish a little, play with my children, take siestas with my wife, Maria, and stroll into the village each evening where I sip wine, and play guitar with my amigos. I have a full and busy life.”
The American scoffed. “I have an MBA from Harvard, and can help you,” he said. “You should spend more time fishing, and with the proceeds, buy a bigger boat. With the proceeds from the bigger boat, you could buy several boats, and eventually you would have a fleet of fishing boats. Instead of selling your catch to a middle-man, you could sell directly to the processor, eventually opening up your own cannery. You could control the product, processing, and distribution,” he said. “Of course, you would need to leave this small coastal fishing village and move to Mexico City, then Los Angeles, and eventually to New York City, where you will run your expanding enterprise.”
The Mexican fisherman asked, “But, how long will this all take?”
To which the American replied, “Oh, 15 to 20 years or so.”
“But what then?” asked the Mexican.
The American laughed and said, “That’s the best part. When the time was right, you would announce an IPO, and sell your company stock to the public and become very rich. You would make millions!”
“Millions – then what?”
The American said, “Then you could retire. Move to a small coastal fishing village where you could sleep late, fish a little, play with your kids, take siestas with your wife, and stroll to the village in the evenings where you could sip wine and play guitar with your amigos.”'
This can be easy or hard depending on how bespoke your application is. If you're using something like Ruby on Rails, then there's a paved road that a scanner can preconfigure to understand your application. If you're using a homegrown authorization framework, then a scanner will likely have a hard time understanding your application and will need to be configured.
* https://blog.r2c.dev/2020/finding-python-redos-bugs-at-scale...
* https://blog.r2c.dev/2020/improving-redos-detection-with-dli...
The culmination of this work was a Python regex linter that could automatically detect ReDoS expressions with fairly high accuracy - Dlint's DUO138 rule: https://github.com/dlint-py/dlint/blob/master/docs/linters/D....
In my opinion, the best solution, as this article mentions, is to avoid the bug class altogether by using something like RE2 when possible. Nevertheless, I found ReDoS to be a really cool bug class at the intersection of computer science and software engineering.
Of course Python imports can have side-effects, so you can achieve the same results with 'import malicious_package', but the installation avenue was surprising to me at the time so I created a simple demo. Also consider that 'import malicious_package' is typically not run as root whereas 'pip install' is often run with 'sudo'.
As the post mentions, I worked on the DAG (an on-prem IdP implementation) for many years, which was based on simpleSAMLphp. So "PHP: a fractal of bad design" was our other north star after the SAML specs for avoiding critical security issues. I spent many hours poring over that blog post trying my best to avoid PHP bugs.
Here was a fun one that occurred due to PHP's wonky in_array behavior: https://simplesamlphp.org/security/201710-01