Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

WordPress 5.8.2 Stored XSS Vulnerability- 760

Karim el Ouerghemmi - Sonar SourcePosted 4 Years Ago
  • In Wordpress, the post slug is the title put into a URL. However, the slug can be manually set by an author.
  • The function sanitize_title() governs how the title to slug transformation is done. When this is done, it converts all characters into ASCII, numbers, underscores and dashes. This sounds restricting but looking at the source code unearths some hidden functionality: the sanitization preserves URL-encoded octets, and, indeed, slugs can contain URL-encoded characters. What can a URL encoded string do for anything though?
  • Within post.php, the slug will eventually be URL decoded. If the slug does contain any URL-encoded characters, it gets encoded once again. Here is where the problem occurs: utf8_uri_encode only encodes Unicode characters. Crazily enough, utf8_uri_encode('<script>alert(1)</script>', 200) will output <script>alert(1)</script>. So, the URL encoding does not work as expected on the way back!
  • This functionality exists within the call to __truncate_post_slug(). The only time this gets called is when Wordpress is saving a post that has the same slug already. Since the post slug should be safe, but can now have arbitrary input, the character expectations have been violated. Pretty quickly the authors found an easy place that XSS was triggered on the page.
  • The fix for the vulnerability was to properly URL encode the data after the modification. According to the authors, extra care needs to be taken when modifying a value once it has been sanitized. Overall, this is a super interesting vulnerability that would only be possible to find through source code review and confirming assumptions about the code path.