WordPress插件开发中的安全性

时间:2016-02-12 作者:Kivylius

我的插件是Mailer。WordPress的应用程序,我已经完成了85%,在发布之前,我专注于安全性。在提问之前,我应该概述一下插件体系结构:

插件能够接受username &;password 和相对imap/smtp 服务器详细信息

  • 验证详细信息并确保输入了正确的imap/smtp(建立了有效连接)
  • 使用EKEY 存储在class.client.phpCONST
  • password 已加密(不能根据需要作为纯文本进行散列imap/smtp) 并使用CKEY 存储在class.client.php.

    使用cookie和用户数据对数据进行解密。

    现在谈谈WordPress的安全问题。我在wp工作了大约3年,无法理解这些,无法找到任何关于它们的信息:

    其他插件可以访问我的插件代码吗?e、 g。require("../plugins/mail/class.client.php\') 和电话new Client()? 如果是这样,我如何防止它,为什么允许这样做Client 班如果是的话,你能推荐一个地方来存放它吗Client() 这个插件的类可以访问这个current_user_can() 和nonces 但这是否足以为AJAX添加足够的安全性?nonces可以过期吗?我在哪里读到更多关于安全、ajax和;web应用程序multisite 从我的方案中创建任何添加问题

    class.client.php

    final class Client {
        const SALT = "bsas8D889b8989sHBsd"; // hash salt
        const EKEY = "23123asdas9dsbbad96"; // db encryption key
        const CKEY = "b797a78skj15hjhHJDa"; // cookie encryption key
        private static function GetUserData(){
            return $this->decrypt_data()
        }
        public static function StoreUserData($data){
            return $this->validate_and_store();
        }
        public static function GetEmails(){
            return $this->show_emails($this->GetUserData());
        }
    }
    

    class.admin.php

    final class Admin {
        public function __construct(){
            add_menu_page(\'mlr\', \'mlr\', \'manage_options\', \'mlr\', array($this,\'admin_page\'));      
        }
        public function admin_page(){
            $user = new Client();
            echo $user->GetEmails();
        }
    }
    
    我的最终目标是,其他插件无论是否感染(后门等),都无法访问username/password/mail 在我的电子邮件中,这是问题的主要部分。加密并存储在数据库中的用户数据只能使用Cookie和$key; $key 是必须的易受攻击的物品。

    很抱歉发了这么长的帖子,但我需要了解我内心的这些问题,希望能有一些见解和建议;帮助

    谢谢

  • 1 个回复
    SO网友:bosco

    What my ultimate goal is, other plugins be it infected(backdoor etc) or not cannot access the username/password/mail of my email, that is the main part of the question.

    The only way to be sure of this is to not store them in a manner than can be automatically decrypted in the database/filesystem - which is to say, not store them in plain-text or an automatically decryptable fashion at all.

    I\'d recommend concatenating/hashing your own security salts and keys with those configured for WordPress itself - you should never distribute a plugin that uses hard-coded salts as anyone with the plugin is basically handed the keys to whatever\'s been hashed for every installation. By adding in the WordPress installation\'s own salts, should you discover that your plugin is vulnerable you can update the salts and invalidate credential stores of all installations when the plugin update is pushed. If an individual installation becomes compromised, a user can change their WordPress salts and likewise invalidate their credentials without altering the plugin.

    Can other plugins access my plugin code? e.g. require("../plugins/mail/class.client.php\') and call new Client()?

    Yes.

    If so, [...] why is this allowed?

    It\'s not "allowed" so much as it is a consequence of interpreted scripting environments. "Extending WordPress" with themes and plugins is just that - it\'s modifying WordPress\'s execution using raw source to achieve the desired outcome. I know of no interpreted language that actually provides reliable mechanisms to "lock" portions of source-script from other portions within the same code-base. Operating systems, sure.

    Rather this responsibility falls onto the execution environment and whoever controls it.

    How do I prevent it?

    It may be possible to achieve using some seriously complex sand-boxing and running different portions of WordPress in different threads - but this is not at all how WordPress is designed, and would take heavy environment re-configuration to boot. Even then, it would still be susceptible to some variety of attack - despite Google Chrome\'s sandboxed JavaScript, malicious code still emerges capable of defeating the measures.

    As with all information security, it should be assumed that if the environment is compromised, so too is everything in and on it, regardless of security measures in place. Even binary viruses in sandboxed environments and those executed in virtual operating systems can break out of their confines to harm the host system, if designed with such scenarios in mind.

    If the consumers of your plugin fail to properly secure their WordPress installations or install compromised code, there is no portion of the filesystem or database that can be considered "safe" for critical information to reside. The same as if a virus finds it\'s way onto your computer, no program or document can be trusted to remain unadulterated or unexposed - if you store passwords in a plain-text file, you must assume that all relevant accounts are compromised or vulnerable. Here as everywhere else in the IT security world, users should not install executables that they do not trust or understand - those who do not have a good basis to differentiate between trustworthy or well-implemented programs should have a limited ability to acquire and/or install such items.

    In short, if you yourself do not directly control the WordPress installations on which your plugin is installed, you cannot prevent your plugin from becoming compromised beyond following good security practices in your implementation.

    Can other plugin read the contents of the file as I\'m storing the encryption key in Client class?

    Yes. In fact, any plugin could parse the WordPress installation\'s wp-config.php file and obtain the database information and salts should it\'s author desire. The thing is, a plugin needn\'t even do that to compromise an installation as the PHP and WordPress environment already give plugins what amounts to free-reign over the database and filesystem to achieve their ends, insofar as the database and filesystem themselves permit. Without these abilities, plugins would be extremely limited in scope.

    If so can you recommend a place to store that so that only Client() class of this plugin can access this?

    No. Credentials stored and/or transmitted as plain-text are never completely "safe", period.

    If your application requires such storage/transmission, then the credentials can only be as safe as the environment in which they\'re stored. You can add additional hoops to obfuscate the credentials, but the fact remains that if your code has everything it needs to decrypt the credentials, then so too does any other code within the environment. It is essentially the same as storing an encrypted file containing passwords on your computer alongside a shell script that decrypts the file as soon as executed. The best way to keep them safe is to secure the environment.

    I\'m using current_user_can() and nonces but is this enough for add sufficient security to AJAX?

    It depends on the specifics of your application and what\'s being transmitted via AJAX. Generally, these mechanisms when implemented properly are sufficient to validate that AJAX requests are being made from a consistent source. However, they in and of themselves are only a component of AJAX security. As general rules of thumb:

    • Do not take any action until the request is "sufficiently" verified, including the use of current-user_can(), check_ajax_referer()
    • Escape, validate, and sanitize all the things that comprise dynamic data. These practices are imperative to prevent SQL injections, arbitrary PHP execution, and delivering malicious JavaScript to visitors. This includes $_GET, $_POST, and $_COOKIE data as well as anything retrieved from the database that will be evaluated as PHP or sent to the browser. Learn which WordPress functions handle the tasks for you - but when in doubt, perform them yourself until you can be sure.
    • If you control the server environment, Secure your site with an SSL certificate and operate over the HTTPS protocol in order mitigate the chances of man-in-the-middle attacks (the Let\'s Encrypt project is well on it\'s way to offering trustworthy certificates for free).
    • Ensure that your error-handling is implemented in such a manner that if your server-script chokes or is accessed directly by a client, no sensitive data is spat back to the browser.

    Can nonces be expired ?

    Yes - WordPress provides the nonce_lifetime filter for this purpose. By default a WordPress nonce is valid for 12-24 hours.

    Can multisite create any additions problems from my scenario?

    It depends on how your plugin is installed and you intend for it to be used in a multisite environment - the potential "problems" that could arise might actually be desire-able outcomes depending on what you\'re gunning for.

    You may want to store mail credentials as user or site-specific data depending on who should have access to which mail - you may even want to implement custom roles and capabilities to provide finer-grained access to mailboxes.