Kiri Kiri Basara, a lesson in domains

Howdy!  If you’re here, one of two things happened.

Either you follow me on social media or my blog and found this new post, or you’re an anime fan watching Occultic;Nine, and saw the domain kirikiribasara.com in episode one and tried typing it into a web browser.  That domain — for now — redirects to here.

Here begins the lesson:

If you’re ever using a domain name in a movie, or a tv show, or in a presentation — any form, really — do yourself a favor and make sure you buy the domain before you go live.

It’ll cost you like $12, tops.  If your show flops, no big deal.  You don’t need to renew it for a subsequent year.  But if it takes off — or even if someone pulls up the domain just right after airtime, it’s a great tool to engage your users.

Or, you could not buy it, and some rando on the internet (hi there) can scoop the domain up for $12 on Google Domains.  Or cheaper if I wanted to go elsewhere.

Also, if you would like to start your own affiliate blog (like the domain was used for in the anime), I’d suggest building at WordPress.com!

As an aside, I’m not really looking to sell the domain, I just think it’s funny, but if anyone does desperately want the domain to run some sort of fan-forum or if the show’s producers are interested, feel free to drop me a line — the contact form on this site should work, and I’m fairly easy to reach on social media. 🙂

Understanding Security Holes

Just finished my talk on Secure Code at WordCamp Philly 2015!  Thanks to everyone who came, here are my slides:

Please Don’t Hack Core

Especially to neuter Core’s ability to upgrade itself.

After I published this, I had someone from cPanel reach out to have a more in depth conversation than it’s really possible to manage in a medium that caps you at 140 characters.

https://twitter.com/cpanelcares/status/597886956945711107

In the interest of transparency and context — as well as showing cPanel’s efforts thus far in working to fix things, here’s the conversation that transpired on that ticket — #6489755 on their internal ticketing system.  Any modifications on my part are purely for formatting, as well as omitting names of customer support folks.


cPanel:

Are you using the cPAddons tool within the cPanel interface to install & manage WordPress? If so, then yes, we disable the auto-update functionality within the application so the updates can be managed from the cPanel interface itself. The way our cPAddons tool tracks software is not compatible with the way WordPress updates, hence why we disable the auto-updates so we can track it through cPAddons.

If you’re not using the cPAddons tool to install/manage WordPress and have concerns of us modifying the core of the application, please let me know.

Regards,


*********** ********
Technical Support Manager
cPanel Inc.

Me:

I’m a Core Contributor to WordPress, not a cPanel User. I was speaking up on Twitter because I learned through some Forum threads that y’all were doing some very problematic things — which I’m hoping to address here.

Just to make sure we’re talking about the same thing, the three changes that I’m aware of are specifically noted are:

get_core_updates()

Short-circuited with:

# cPanel override: Disable all core updates to prevent conflict with cPAddons.
return false;

core_upgrade_preamble()

Short-circuited with:

# cPanel override: Do not display the current or the latest version, because we've disabled updates.
return;

WP_Automatic_Updater::is_disabled()

Short-circuited with:

return true; // Force this functionality to disabled because it is incompatible with cPAddons.

(Please note that all my code references to WordPress core are aimed at the latest revision of the `master` branch on GitHub)

It looks like when you’re hacking core, you’re turning off not merely Automatic Updates (as you suggested prior), but all WordPress Updates as a whole. This is a Very Bad Thing. If you were merely disabling Automatic Updates, but still leaving the user with the ability to use WordPress’s very well established upgrade system, that would be something else entirely — and in fact is documented extensively here: https://make.wordpress.org/core/2013/10/25/the-definitive-guide-to-disabling-auto-updates-in-wordpress-3-7/
— and can be done by adding a single line to your generated wp-config.php file when installing WordPress:

define( 'WP_AUTO_UPDATE_CORE', false ); # Disables all automatic core updates:

Why do you feel the need to fully disable all updates from within WordPress and force users to use either cPanel or FTP exclusively to upgrade WordPress? Why can’t they work in conjunction with one another?

Clearly, users have been dismayed and shocked when their installs haven’t been notified of security point releases that are available as y’all have killed the `get_core_updates()` function. Many don’t even realize they may need to go into cPanel to upgrade their WordPress install, and so their installation is left at an outdated, insecure version that is incredibly vulnerable to exploit.

cPanel:

 Thanks for the followup. The WordPress management through cPAddons is quite old, and very well may have been in place prior to having define( 'WP_AUTO_UPDATE_CORE', false ); within the WordPress application. I’m uncertain of that as I do not know when WP introduced that function but from Googling it the oldest result I can find is from 2012.

That said, cPanel does in fact do a few things with cPAddons in regards to customers who have out dated versions:

  • Whenever WP releases a maintenance build that addresses security concerns, we react very quickly to get our software updated to be available to customers.
  • By default, we define that software managed/installed through cPAddons is automatically updated when a new update is available.
  • Based on the above information, if the server administrator leaves the defaults enabled, once WP introduced a maintenance releases that corrects security concerns and we’ve tested and updated our source for it, customers will receive the release automatically.
  • If the server administrator decides to disable automatic software updates, the end user and systems administrator will still receive notifications that their installation is out of date accompanied with steps on how to update their application.

With that, I can definitely appreciate the concern for making it as easy and automated as possible for users to get updates for their WordPress, there’s definitely more to the situation that solely disabling WordPress’ automated updates in the core.

I’ve submitted a case (#188545) with our developers to have the logic for disabling updates changed from it’s current behavior, to using define( 'WP_AUTO_UPDATE_CORE', false );.

If you have any other questions, feedback, or concerns, please don’t hesitate to let me know.

Me:

By default, we define that software managed/installed through cPAddons is automatically updated when a new update is available.

Clearly, that’s not the case in practice. As the user who discovered this remarked:

In my audit, it appears that — of 37 total WP-based websites on our server — we have 14 that have not updated to the latest version of WordPress. Of those 14, the oldest version is 3.9 (which 3 of 14 are running), and the newest is 4.1 (which 4 of the 14 are running).

Source: https://wordpress.org/support/topic/wp-updates-not-showing-latest-wp-version-available?replies=34#post-6612888

If cPanel wants to manually update sites to current releases, I’m fully, 100% in favor of that. It’s a solid step to a safer, more reliable web.

My issue is that y’all are preventing users from updating themselves via the existing WordPress infrastructure. There’s really no reason for the blocking of an existing stable upgrade system. If you just need some way for cPanel to be notified on core upgrades, it’s relatively trivial to set up a perhaps 20 line function that will notify cPanel when it happens — and that will even account for users manually updating their WordPress installation via FTP, which your current version seems as though it would break during.

Here’s a proof of concept:


<?php
/**
* Compares a stored version of the WordPress version to
* the current version.
*
* If the current version has changed, update the stored
* version and run custom code that notifies cPanel that
* an update has occurred.
*/
function cPanel_wp_version_check() {
$old_version = get_option( 'cPanel_wp_version' );
if ( $GLOBALS['wp_version'] !== $old_version ) {
$new_version = $GLOBALS['wp_version'];
update_option( 'cPanel_wp_version', $new_version );
// DO THINGS HERE TO NOTIFY CPANEL OF SOFTWARE UPGRADE.
}
}
add_action( 'init', 'cPanel_wp_version_check' );

Does that make sense?

Also — I’m not a lawyer, but distributing a forked version of WordPress and still calling it WordPress (rather than cPanelPress or something) may be a trademark violation. Forking is 100% fine under the GPL for copyright on the code, but may be problematic from a trademark perspective — as what you’re distributing isn’t actually WordPress, but rather a hacked up version. If that makes sense?

cPanel:

Thank you for contacting us regarding people’s experience using WordPress as distributed via our Site Software feature. This feature is a method of installing and managing various third party applications. Applications installed via Site Software are intended to be managed entirely within Site Software, thus in-application updaters are disabled. Allowing the in-application update to proceed will cause a conflict between the updated application and the Site Software, which can easily result in confusion. From this perspective what we are doing is no different from Debian and other Linux distros that distribute applications with in-application updaters.

We generally release the latest version of WordPress within 1 to 5 days of the latest WordPress update. At minimum server administrators are informed each night of all Site Software applications that need updated. It is up to user’s to configure their notifications within cPanel to receive such updates.

Within the Site Software user interface, users are able to upgrade all applications that are out of date. In the admin interface, a server admin can choose to upgrade all Site Software applications on the entire server.

Based upon what the Drumology2001 user reported on the forum it appears something is amiss on that server. We’d love to examine that server to determine why WordPress updates were not available to the user. Based upon the fuzzy dates used on the forum, and compared with our internal records, the 4.1.1 update was available to the Site Software system prior to the initial post. We’ll reach out to him to determine whether there is anything we can do there.

I’d also like to thank you for pointing us in the direction of the various ways to manage WordPress updates (https://make.wordpress.org/core/2013/10/25/the-definitive-guide-to-disabling-auto-updates-in-wordpress-3-7/). We are currently reviewing, and discussing, these to determine which fits the Site Software distribution method the best. Using a method within the application to disable updates is usually preferred.

One of our concerns is that in-application updaters are incompatible with the Site Software distribution method. There are various things that could happen due to updating a Site Software managed application outside of Site Software. At minimum it means that from that point onward the server admin, and potentially the user, will be informed of a software update that is no longer needed. At worst someone will force an update that results in corrupting the installed application.
Handling those in a way that reduces frustration for everyone, and keeps support costs down is important to us.

Based upon the experience of the three users that posted to that thread (Drumology2001, echelonwebdesign, and sg2048) it is apparent there is room for other improvements within the system, such as update notifications. We’re taking into consideration their experience to determine how we can making WordPress hosted on a cPanel & WHM server a better experience for all.

Me:

 To summarize, my argument is largely a pragmatic one.

You can’t prevent a user from updating the software outside of the cPanel Site Software Distribution Method (gosh, that’s a mouthful, I’ll call it the CPSSDM from here on out) — as they could always just use FTP to update the software.

From a software architecture perspective, this is problematic — and it would be far simpler to develop around it so that any software updates run — whether via FTP, a remote management tool (such as ManageWP, InfiniteWP, Jetpack Manage, iThemes Sync, etc), via the WordPress Dashboard, or an Automatic Update — successfully apprises the CPSSDM of the update.

Long story short, WordPress updating itself, and the CPSSDM managing updates shouldn’t be a conflict, they should behave in concert with one another, complementing each other in their behaviors, rather than stomping across the sandbox to kick over the other’s castle.

As mentioned above, I’d be delighted to volunteer my time and expertise to help the CPSSDM have an integration that doesn’t involve hacking core files and potentially leaving users running insecure software.

cPanel:

Thanks for the follow up and summary. We both agree there are improvements to be made, as with any software – it’s never ending. We will definitely reach out directly once your expertise is needed to make sure we’re providing the absolute best experience we can to both of our customers.

Thank you again, and keep that feedback coming!


So, in then end I don’t know where things are going from here.  I know that a lot of users find it super convenient to use one click installs for WordPress, and I really hope that users who take the short-cut of one-click installs don’t wind up dead ended on an old insecure release because of some sort of server misconfiguration and hacked core files.

I’m also optimistic, because cPanel seems willing to take suggestions and input from the community on best practices.  After all — let’s face it, when they’re providing one click installs for dozens of software projects, they’re not going to be able to work with each software project individually to make sure they’re doing it the best way possible.  A lot is dependent on the communities reaching out and offering to help them do it the right way.

I look forward to hearing back from cPanel and seeing their integration done in a way that works well and plays nice with everyone else in the sandbox too.

After all, I think we all want sustainable, stable integrations — not fragile bits of code that will break if a user upgrades the wrong way. 🙂

News Flash: The FBI doesn’t want you to encrypt your data.

So, yesterday FBI Director James B. Comey criticized Google and Apple for deploying encryption on smartphone operating systems that they wouldn’t be able to bypass, even when presented with a valid warrant by police. (source)

Does he not grasp that the reason people want this extra security is because of government surveillance overreach and secret warrants?  They’ve literally brought this upon themselves.  When you deny people their privacy in everyday things, they feel it necessary to go to further extents to maintain it.  Were it not for NSA overreach, lying before congress, secret FISA courts and the like, this recent push to encryption likely would never have happened.

So, well done. I’m personally delighted that folks are opting to encrypt things.  Thanks for giving them that push towards it by being something of an overly attached significant other.

nsa-memes-2

Twitter oEmbed is Leaking Data

oEmbeds are fun.  They make it easy to embed third-party content on your site, like tweets, status updates, videos, images, all sorts of stuff.

Unfortunately, to do this, third-party code gets injected into your page.  Don’t worry, this is by design, but it does mean that you should only oEmbed from reputable sites.  WordPress Core is very picky as to the providers that it chooses to accept as oEmbed sources.

Twitter is one of these oEmbed providers.  Here’s an example of an embedded tweet:

Neat, isn’t it?

Now, hover over my name.

See that little url that shows on the bottom left corner of your browser (probably)?  It probably looks just like http://twitter.com/daljo628!

Now, click it.  Don’t worry, I’ll wait.

Did the page you landed on have a bunch of extra cruft appended to the end of it?

Maybe it looked something like https://twitter.com/daljo628?original_referer=http%3A%2F%2Fstephanis.info%2F2014%2F05%2F22%2Ftwitter-oembed-is-leaking-data%2F&tw_i=469505591946129408&tw_p=tweetembed?

If you right-click and inspect the element, the URL is just what you expected! If you right-click and open in a new tab — same thing! But if you click normally and let it trigger a Javascript event, it modifies the link before your browser actually processes it.

After you’ve clicked on it normally once, you can come back and re-inspect it, to see that the URL on the link has now changed to the one with the referer data on it — they’re rewriting it inline and intentionally delaying it so when you first click, you wouldn’t realize that the data was being appended.

This can be a problem because some sites employ concealers for the referer http header (No, I didn’t misspell referrer) like href.li for example. By embedding this in a get parameter forcibly, it’s leaking data in a way very difficult to block, by taking advantage of the trust offered via accepting Twitter as an oEmbed provider.

Pressgram Security Concerns

NOTE: This is the first of two posts looking at problems I see with Pressgram. The second, addressing the Terms of Service can be read here.

Hi, folks. Gather round, and let’s have a little chat about password security and transparency.

So Pressgram just released, after a rather successful Kickstarter campaign, and lots of excitement by the community. Hurrah, congratulations, folks! Getting a public release actually shipped is the toughest part of any project, and you’ve got that out. Well done!

I installed the app last night, kicked the tires, and examined how it operates a bit, and I’ve got some concerns that I’d like to voice.

First, though, a bit of background. On the official WordPress Mobile Apps, there’s only so much security that can be reasonably achieved via the XML-RPC API that they (and pretty much all apps) use. With XML-RPC, there are no authentication tokens, you need to send your password in plaintext. Which is normally totally fine, as the password is just stored by your local phone (the security of which you are responsible for yourself), and then stored in a double-hashed and salted form on the server.

It seems that, unlike the WordPress Mobile Apps, the password that you enter in Pressgram isn’t kept private on your own device. Without noting it on a Privacy Policy or in any way notifying you that Pressgram is doing it, your password is stored in plaintext on their server. Which — to be fair — is necessary, if they’re going to be pushing data from the Pressgram Server to your WordPress site, and not going to require having a specialized plugin (like Jetpack) installed on your WordPress site to do it. And I don’t think that Jetpack is necessarily a worthwhile dependency to have for an app like this.

My first concern is that I don’t really like my passwords being stored in plaintext on a third-party server that could be hacked (or for that matter, required to be turned over by an order from a FISA court). Some other applications, such as IFTTT do the same thing, but at least with them, it’s transparent that it’s going to be their server holding your credentials and accessing your WordPress site.

With Pressgram, without further investigation, one would believe that it’s the app directly uploading the files to your WordPress site. After all, that’s what the Kickstarter initially pledged:

I suppose another way you could say it is… it’s your filtered photos published directly to your WordPress-powered blog, when you want, where you want, how you want.

But that’s not the case! For the curious, here’s what I saw when running a test against a honeypot standalone site where I was trapping all the requests sent to it:

Firstly, the App sends two requests to /xmlrpc.php

XXX.XX.XXX.XXX - - [06/Sep/2013:02:51:51 +0000] "POST /xmlrpc.php HTTP/1.1" 200 904 "-" "John.Saddington.Pressgram/1.0 (unknown, iPhone OS 6.1.4, iPhone, Scale/2.000000)"
[Fri Sep 06 02:51:51 2013] [error] [client 174.59.108.165] <?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>
XXX.XX.XXX.XXX - - [06/Sep/2013:02:51:52 +0000] "POST /xmlrpc.php HTTP/1.1" 200 512 "-" "John.Saddington.Pressgram/1.0 (unknown, iPhone OS 6.1.4, iPhone, Scale/2.000000)"
[Fri Sep 06 02:51:52 2013] [error] [client 174.59.108.165] <?xml version="1.0"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value><string>admin</string></value></param><param><value><string>password</string></value></param></params></methodCall>

These two requests firstly make sure that the site is there and is a WordPress install, and secondly makes sure that the credentials work — and if it’s a multisite install, returns the available blogs.

So far, so good. The User Agent strings are clear as to what they are and what they’re accomplishing.

Then, ten requests come in:

YY.YYY.YYY.YYY - - [06/Sep/2013:02:53:27 +0000] "POST /xmlrpc.php HTTP/1.1" 200 1845 "-" "-"
[Fri Sep 06 02:53:27 2013] [error] [client YY.YYY.YYY.YYY] <?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
<methodName>wp.getTerms</methodName>
<params>
<param>
<value>
<int>1</int>
</value>
</param>
<param>
<value>
<string>admin</string>
</value>
</param>
<param>
<value>
<string>password</string>
</value>
</param>
<param>
<value>
<string>category</string>
</value>
</param>
<param>
<value>
<array>
<data/>
</array>
</value>
</param>
</params>
</methodCall>

and nine others very much like it. If anyone is curious to see them, tweet me, and I’ll post them for folks to review. Checking existing taxonomies, creating new terms, uploading the photo, and creating the post.

XXX.XX.XXX.XXX is the IP address of my phone. YY.YYY.YYY.YYY is the IP Address of the Amazon Cloud Server that Pressgram works off of. I’ve anonymized these just for the sake of privacy. They’re easy enough to find, but it’s not my business to release them. I’ve also removed the base64 encoded image data.

I’ve also captured the request that the Pressgram App uses to send your password up to the Pressgram server — it looks something like this:

URL: https://api.pressgr.am/index.php/Api/postPhotoData
Data:
{
	"social": {},
	"post_content": "Pic",
	"sessionId": "00000000000000000000000000000000",
	"blog": [{
		"title": "Pic",
		"password": "password",
		"login": "admin",
		"url": "honeypot.example.com"
	}],
	"identifier_photo": "0000000000.0000000000"
}

So at least it’s being sent to the Pressgram server over HTTPS.

You’ll notice that the requests coming from the Pressgram Server have no User Agent to identify what they’re there for. They’re all signed with username and password — meaning that the Pressgram servers now have my username and password in plaintext, with not even a notification to me in their Privacy Policy or Terms of Service that this is being transferred up to their servers.

So what does this all mean?

Well, it means that Pressgram is storing your credentials in plaintext (or potentially encrypted alongside a decryption key) on your behalf, without notifying you or doing anything publicly to indicate that this is the case. No matter how high entropy your passwords may be, if you hand it to someone and they get hacked, it doesn’t matter. You are vulnerable — doubly so if you use that password for other accounts as well.

To some folks, this may be a worthwhile tradeoff. But as I look at it, I don’t see it as a necessary tradeoff. Your credentials could just as easily be kept private between the app on your phone, and your WordPress site. Just have your phone upload the photo directly to your WordPress install. It wouldn’t be difficult to do, it’s already making XMLRPC requests to the server. And it fulfills the initial Kickstarter promise of “your filtered photos published directly to your WordPress-powered blog”. It also would provide the added security that if Pressgram is eventually shut down or sold off, the app would still function, as it’s not needlessly dependent on the Pressgram Servers.

To protect yourself, you may want to consider making a seperate account for your WordPress site with the Author role, and using those credentials with Pressgram, and make sure you’re using a distinct password — as well as with any service that you provide a password to.

Conclusion

So in the end, what am I calling for?

Ideally, I’d like to see Pressgram give users the option of simply taking photos, and uploading them directly from the app to their WordPress blog. No servers in the middle with potential vulnerabilities for your data. In short — make the account creation and login optional. Give folks a choice! That sounds a lot more like what the Kickstarter was proposing. If you’d like to build a new social network on top of it (if I had a dime every time a potential client tried building that), make it optional!

Do I see that happening? Well, I hope so, but I’ve found that companies don’t normally like to make themselves less integral to a process. So at the very least, notify your users that their credentials are going to be stored on your servers. To take them as Pressgram has without any such public warning I see as morally questionable, and totally contrary to the values of the WordPress community, which embraces transparency, and not forcing unnecessary service dependencies between you and your site.

UPDATE: Pressgram has updated their Terms of Service to indicate that your content may travel through their network to get to your blog.  Unfortunately, it says nothing in the TOS or its Privacy Policy about your username and password being stored on or passing through its servers.

My Two Cents on Two Factor

Two-factor authentication should (imho) be in core, but core can’t always provide the best ways to accomplish it, for example, text messaging which requires external APIs.

What I see the best fit being, is this:

There is a framework for Two-Factor Authentication in core, that provides two free no-api-required methods for users to select to validate:

  • Email (with a warning that it’s not as secure)
  • Time-based One-time Password Algorithm (TOTP)
    • This is what Google Authenticator / Authy use.
    • IETF RFC6238

Beyond this, Core would offer a filter to permit plugins to register other authentication methods, for example, Duo Security’s push-based request system, or Jetpack could provide a gateway for text-messages, just as they are sent from WordPress.com.

We would also need to allow a define( 'DISABLE_TWO_FACTOR_AUTH', true ); line in wp-config.php that would switch it off, in case a site owner lost their phone and needed to disable it temporarily.  I could also see use for a customized define to only disable it for a given user.  Ideally this would add a warning to the adminbar for all users that have manage_options() to notify them that it has been disabled.

Other dependencies that would need to be in core:

  • Application Passwords
    • For systems where the user cannot be prompted for a two-factor auth code (XMLRPC, etc), disallow their normal password for authentication, and force them to use a generated application password that is stored in usermeta.
    • For systems where the user can be prompted for a two-factor auth code (wp-login.php) don’t permit the use of application passwords.
  • Backup Auth Codes
    • Saved in usermeta, not terribly much interesting here.