如何修复base64_encode和base64_decode以避免注入?

时间:2016-04-19 08:14:24

标签: wordpress code-injection

我正在使用带有base64_encode和base64_decode的WordPress主题选项。由于base64_代码注入的风险,需要更改该代码。 实际上我不知道该怎么做。

包含base64_encode的代码如下:

conf

并且代码内容base64_decode是这样的:

                    new AjaxUpload(<?php echo ($value['id']); ?>, {
                        action: '<?php echo THEME_DIR; ?>/admin/upload-file.php',
                        name: '<?php echo ($upload_security)?>',
                        data: {
                            upload_path : '<?php echo base64_encode(UPFW_UPLOADS_DIR); ?>'
                        },
                        onSubmit: function(file, ext){
                            //Check if file is an image
                            if (! (ext && /^(JPG|PNG|GIF|jpg|png|jpeg|gif)$/.test(ext))){ 
                               // extension is not allowed 
                               status.text('Only JPG, PNG or GIF files are allowed');
                               return false;
                            }
                            jQuery('#<?php echo ($value['id']); ?>loader').addClass('activeload');
                        },
                        onComplete: function(file, response){
                            //On completion clear the status
                            status.text('');
                            //Successful upload
                            if(response==="success"){
                                $file = file.toLowerCase().replace(/ /g,'_').replace(/(_)\1+/g, '_').replace(/[^\w\(\).-]/gi,'_').replace(/__/g,'_').replace(/#/g, '_');
                                //Preview uploaded file
                                jQuery('#<?php echo ($value['id']); ?>preview').removeClass('uploaderror');
                                jQuery('#<?php echo ($value['id']); ?>preview').html('<img class="preview" src="<?php echo UPFW_UPLOADS_URL; ?>/'+$file+'" alt="<?php echo ($value['id']); ?> Image" />').addClass('success');
                                //Add image source to hidden input
                                jQuery('input#<?php echo ($value['id']); ?>').attr('value', '<?php echo UPFW_UPLOADS_URL; ?>/'+$file);
                                //Append thumbnail to gallery
                                jQuery('.thumbs').append('<a class="preview" href="<?php echo UPFW_UPLOADS_URL; ?>/'+$file+'"><img src="<?php echo UPFW_UPLOADS_URL; ?>/'+$file+'" /></a>');
                                //Save Me Fool
                                activate_save_animation();
                            } else{
                                //Something went wrong
                                jQuery('#<?php echo ($value['id']); ?>preview').text(file+' did not upload. Please try again.').addClass('uploaderror');
                            }
                            jQuery('#<?php echo ($value['id']); ?>loader').removeClass('activeload');
                        }
                    });

真的很感谢你的帮助。

谢谢。

1 个答案:

答案 0 :(得分:0)

将这一点从评论转移到答案,因为这将得到详细解读,并希望它会成为人们链接到各地的那些很酷的Stack Overflow答案之一,我会得到各种各样的赞成当地酒吧提供工作和免费饮料。好吧,我会满足于赞成。或饮料。

嘿,我今天回家了。宝宝睡着了。我有时间絮絮叨叨。

的base64

事情并不像现在那样标准化。例如,计算机我从Commodore 64中获取用户名,使用Commodore专有的PETSCII而不是ASCII编码字符。许多IBM大型机都使用自己的EBCDIC编码,这种编码基于旧机器使用的六位字符编码。六位可以表示值0-63或64个不同的字符。

还有一些字符特殊的事实。它们代表标签,不可见空间和数据传输控制协议之类的东西。 ASCII 7是&#34; BEL&#34;这实际上会在ASR-33电传打字机上响铃。但是这些角色在不同的地方并且在不同的角色编码中意味着不同的东西。

确保电子邮件&amp; Usenet在这些古老的系统和现行标准之间工作,早期的互联网先驱们提出了base64编码,它将8位数据一次六位编码成一组64&#34;可打印&#34; (不是控制)字符。你仍然需要在另一端将它解码为8位,但它沿途传递的任何旧的6位或7位系统都无法搞砸。

所有base64_encode()base64_decode()所做的就是使用有限的标准字符集对数据进行编码。将二进制数据(如照片)存储在数据库中或用HTML编码它们非常方便&lt; img&gt;标签。这是一种围绕反斜杠转义的方法,有时在PHP中会自动发生。但它不是一种加密或任何东西。

但是base64编码的文本对旧的大型机很友好,而不是人。例如,&#34; Hello World&#34;成为SGVsbG8gV29ybGQ =。这就是为什么人们用它来隐藏邪恶的代码或他们不想改变的东西,如版权通知或链接回到主题建设者的网站:

echo 'Get great answers at <a href="http://stackoverflow.com">Stack Overflow</a>';

变为

eval(base64_decode('ZWNobyAnR2V0IGdyZWF0IGFuc3dlcnMgYXQgPGEgaHJlZj0iaHR0cDovL3N0YWNrb3ZlcmZsb3cu Y29tIj5TdGFjayBPdmVyZmxvdzwvYT4nOw=='));

是WordPress.org主题审核小组不想看的内容。这是他们关注的base64的使用。这是人们模糊代码的一种方式,使人们无法阅读它。这是冒险的,它违背了开源精神。

您的示例代码

此代码很危险:

data: { upload_path : '<?php echo base64_encode(UPFW_UPLOADS_DIR); ?>' }

UPFW_UPLOADS_DIR是服务器上的某个目录,它只是被base64编码。这意味着您的JavaScript AJAX代码会发送一个变量upload_path,其值为L3Zhci93d3cvbXlzaXRlL3dwLWNvbnRlbnQvdXBsb2Fkcw== - 只有/var/www/mysite/wp-content/uploads base64编码。

服务器上的PHP代码获取该值并对其进行解码:

$uploaddir = base64_decode( $_REQUEST['upload_path'] ) . "/";

然后将文件名附加到该目录以构建文件路径:

$file = $uploaddir . strtolower(str_replace('__', '_', str_replace('#', '_', str_replace(' ', '_', basename($file['name'])))));

并将上传的文件移动到新路径:

if (move_uploaded_file( $_FILES[$upload_security]['tmp_name'], $file)):

此代码是在Web服务器软件(Apache,Nginx或类似软件)可以在磁盘上写入的任何位置上传文件的后门

我可以发布到您的/admin/upload-file.php脚本,并为其提供一个类似L3Zhci93d3cvbXlzaXRlL2luZGV4LnBocA==的upload_dir。您的代码将获取我的文件并用它替换WordPress的主index.php文件(/var/www/mysite/index.php)。

您的代码应该直接使用UPFW_UPLOADS_DIR,而不是将upload_dir发送到浏览器并信任您回复您发送的内容,而不是直接使用UPFW_UPLOADS_DIR:

$file = UPFW_UPLOADS_DIR . '/' . strtolower(str_replace('__', '_', str_replace('#', '_', str_replace(' ', '_', basename($file['name'])))));

您的上传代码看起来像是一个独立的PHP脚本,而不是WordPress's AJAX functionality。如果您喜欢这种方式,则可以通过including wp-load.php 引导 WordPress,以便您的代码中提供其变量,常量(如UPFW_UPLOADS_DIR)和API