
TL; DR: We’re saying a brand new open supply sort checker for Hack, referred to as Hakana.
Slack launched in 2014, constructed with a whole lot of love and likewise a whole lot of PHP code.
We began migrating to a special language referred to as Hack in 2016. Hack was created by Fb after they’d struggled to scale their operations with PHP. It provided extra type-safety than PHP, and it got here with an interpreter (referred to as HHVM) that might run PHP code quicker than PHP’s personal interpreter.
A lot has modified in PHP-land since we switched. PHP is quicker than it was, and it has borrowed numerous Hack options (reminiscent of constructor property promotion). A substantial amount of the PHP group has additionally embraced sort checking — there are actually some nice third-party sort checkers to select from.
Sticking with Hack has given us entry to extra runtime velocity boosts, performance-enhancing language constructs like `async`, and a typechecker that’s extra strict by default than PHP typecheckers. However we’ve missed out on options offered by PHP typecheckers, together with the flexibility to customise sort inference guidelines to seek out points particular to our codebase and automatic safety vulnerability detection.
Slack has tons of of builders writing Hack. We need to give them the absolute best expertise, so final yr we began constructing a kind checker that might fill these gaps.
We’ve dubbed that static evaluation instrument Hakana, and it’s now available on GitHub!
Hakana is predicated on Psalm, an open-source PHP static evaluation instrument I created, and it’s written in Rust. Hakana re-uses a Hack parser that’s bundled with the Hack interpreter.
A bonus of writing it in Rust: with a little bit of prodding, Hakana can run nearly anyplace. For instance, it runs in your web browser through WASM.
How we use Hakana
At Slack we run Hakana in CI to implement good code habits in a variety of areas. Right here’s an incomplete listing:
- It prevents unused features and unused personal strategies.
- It prevents unused assignments inside closures.
- It detects each not possible and redundant type-checks.
- It warns us about potential SQL-injection assaults and cross-site scripting vulnerabilities (extra on this beneath).
- It prevents misuse of inside Slack APIs (through plugin hooks).
We additionally use Hakana to automate type-aware API migrations (once more through plugin hooks) and to delete unused features in bulk. Because of Rust, these whole-codebase migrations are comparatively fast.
Safety
PHP makes it very easy to make a dynamically-rendered web site. PHP additionally makes it very easy to create an totally insecure dynamically-rendered web site.
Hack improves on this barely, by supporting a system for producing HTML output referred to as XHP. XHP is secure-by-default in opposition to cross-site scripting assaults, but it surely doesn’t cease you from leaking buyer information, and Hack doesn’t forestall you from taking pictures your self within the foot with a variety of different safety vulnerabilities.
For a bunch of causes (together with compliance obligations) Slack wanted a instrument that might uncover these vulnerabilities. Psalm, the sort checker that Hakana is predicated on, already does safety evaluation, so it was comparatively easy so as to add safety evaluation to Hakana as effectively.
Hakana isn’t the primary safety evaluation instrument for Hack — for years, Fb has been utilizing an inside, closed-source instrument called Zoncolan — however Hakana is the primary that everybody can use.
Hakana works in a lot the identical approach as Zoncolan. It examines how information can circulate between completely different features in a codebase, and checks if attacker-controlled information can present up in locations it shouldn’t.
Up to now, Hakana has discovered numerous exploitable vulnerabilities in manufacturing code at Slack (that have been instantly mounted, and we checked our logs to make sure that the vulnerabilities had not really ever been exploited).
Safety within the sort system
Hakana’s safety evaluation mode is a type of interprocedural evaluation — it seems to be on the approach information flows between features. Hakana additionally helps detecting one sort of vulnerability (SQL injection) through intraprocedural evaluation, simply by inspecting sorts at perform boundaries.
To do that, Hakana borrows the idea of literal string sorts from Psalm. In Hack code we are able to outline a kind alias:
<<HakanaSpecialTypesLiteralString()>> sort db_query_string = string;
Although the official Hack typechecker simply treats this as a string, Hakana treats it as a particular sort `literal-string`, a subtype of string that may solely be concatenated or interpolated with different literal-strings. Passing a string right into a perform that expects a literal-string causes Hakana to emit an error:
perform get_id_query(string $id): db_query_string
return "choose * from customers the place id = '$id'";
// Error: The kind `string` is extra common
// than the declared return sort `literal-string`
Extending Hakana
PHP static evaluation instruments are usually highly-customisable. Customisable static evaluation is actually helpful for PHP, as a result of its interpreter permits plenty of tips (e.g. magic methods) that may confound one-size-fits-all static evaluation instruments.
Most of these tips don’t work in Hack code, so there’s far much less of a necessity for customisable static evaluation. Even so, we’ve discovered a whole lot of worth in extending Hakana with plugins.
For instance, we use a customized plugin to inform Hakana {that a} methodology name on our inside Outcome
object, $some_result->is_ok()
, is equal to the extra verbose $some_result is ResultSuccess<_>
typecheck.
We additionally use customized plugins to carry out type-aware migrations at velocity throughout the complete codebase.
Constructing a plugin system for Rust just isn’t easy — our customized model of Hakana wraps the open-source core as a library, utilizing its plugin hooks the place essential — but it surely’s an necessary characteristic for us.
Pace
Hakana was tailored from Psalm, a kind checker written in PHP. Whereas PHP is quick for an interpreted language, it may possibly’t compete with a compiled instrument. To research a codebase of Slack’s dimension — many hundreds of thousands of traces of code — we wanted a instrument that’s as quick as doable.
Hakana, written in Rust, runs about 5x quicker than the PHP-based instrument on which it’s modeled.
We haven’t spent a lot time tuning efficiency, however when analyzing the complete Slack codebase (about 5 million traces of code) efficiency is on par with the official Hack typechecker. That’s ok for us, for now.
Why open-source Hakana?
Hack form of seems to be like PHP however with extra sorts. In that respect it’s been in comparison with TypeScript. However not like TypeScript, which compiles all the way down to JavaScript, Hack requires its customers to alter a whole lot of their server infrastructure too.
As a consequence of that top switching value, as we speak Hack is simply used at a number of corporations. It’s doable that no one else apart from Slack may have a motive to make use of Hakana.
Even so, there are a number of the reason why we predict it’s price open-sourcing:
- 🔍 The broader programming language group could have helpful enter — particularly with regards to safety evaluation.
- 🤝 Psalm, one other open-source instrument, was the idea for Hakana. By open-sourcing our personal instrument we’re returning the favor.
- 🏢 Although it wouldn’t be straightforward, corporations with extraordinarily giant PHP codebases may contemplate forking Hakana and altering it to research PHP code.
Conclusion
Slack is an indispensable instrument for hundreds of thousands all over the world. Hack is now an integral a part of Slack, and so we’ve created a instrument that we hope will develop into indispensable to our Hack builders. We’re open-sourcing it today with the hope that others will discover it helpful and attention-grabbing.