Files
roi-theme/wp-content/plugins/PDFEmbedder-premium-secure/core/secure/uploads.php
root a22573bf0b Commit inicial - WordPress Análisis de Precios Unitarios
- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:04:30 -06:00

455 lines
13 KiB
PHP
Executable File

<?php
/**
* Secure Uploader
*
* @since 1.0.0
*
* @package WP-PDF-Secure
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Uploader class
*/
class WP_PDF_Secure_Uploader {
/**
* Undocumented variable
*
* @var bool
*/
protected $pdfemb_secure = true;
/**
* Undocumented variable
*
* @var bool
*/
protected $pdfemb_cacheencrypted = true;
/**
* Undocumented function
*
* @param object $pdfemb_secure PDF secure object.
* @param bool $pdfemb_cacheencrypted Encrypted cache.
*/
public function __construct( $pdfemb_secure = true, $pdfemb_cacheencrypted = true ) {
$this->pdfemb_secure = $pdfemb_secure;
$this->pdfemb_cacheencrypted = $pdfemb_cacheencrypted;
}
/**
* Undocumented function
*
* @return void
*/
public function intercept_uploads() {
// Called in admin_init.
add_filter( 'wp_handle_upload_prefilter', array( $this, 'custom_upload_filter' ) );
}
/**
* Undocumented function
*
* @return void
*/
public function handle_downloads() {
// Called in init.
if ( ! isset( $_GET['pdfemb-serveurl'] ) && ! isset( $_GET['pdfemb-nonce'] ) ) {
return;
}
if ( 'POST' !== $_SERVER['REQUEST_METHOD'] && ! isset( $_GET['pdfemb-nonce'] ) ) {
return;
}
$direct_download = false;
if ( isset( $_GET['pdfemb-nonce'] ) ) {
if ( ! wp_verify_nonce( $_GET['pdfemb-nonce'], 'pdfemb-secure-download-' . $_GET['pdfemb-serveurl'] ) ) {
return;
} else {
$direct_download = true;
}
}
$pdfurl = $_GET['pdfemb-serveurl'];
$filepath = $this->get_secure_path( $pdfurl );
if ( '' !== $filepath && file_exists( $filepath ) ) {
$filename = basename( $filepath );
if ( ! $this->is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // @codingStandardsIgnoreLine
@set_time_limit( 0 ); // @codingStandardsIgnoreLine
}
if ( function_exists( 'get_magic_quotes_runtime' ) && get_magic_quotes_runtime() && version_compare( phpversion(), '5.4', '<' ) ) { // @codingStandardsIgnoreLine
set_magic_quotes_runtime( 0 ); // @codingStandardsIgnoreLine
}
@session_write_close(); // @codingStandardsIgnoreLine
if ( function_exists( 'apache_setenv' ) ) {
@apache_setenv( 'no-gzip', 1 ); // @codingStandardsIgnoreLine
}
@ini_set( 'zlib.output_compression', 'Off' ); // @codingStandardsIgnoreLine
if ( ob_get_length() ) {
ob_clean(); // Clear output buffer in case Unicode BOM was added by a PHP file saved in wrong encoding.
}
nocache_headers();
header( 'Robots: none' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: attachment; filename="' . $filename . ( $direct_download ? '' : '.binary' ) . '"' );
header( 'Content-Transfer-Encoding: binary' );
if ( ! class_exists( 'WP_PDF_SimpleRC4' ) ) {
include_once dirname( __FILE__ ) . '/rc4_simple.php';
}
$sk = $this->get_secret_key();
$filetime = filemtime( $filepath );
$cache_to_file = ( false !== $filetime && ! $direct_download && $this->pdfemb_cacheencrypted
? $filepath . '.encrypted-cache.' . md5( $filetime . '-' . $sk ) . '.pdf'
: '' );
$myrc4 = $direct_download
? new WP_PDF_DirectRC4( '' )
: new WP_PDF_SimpleRC4( $sk );
$this->readfile_chunked( $filepath, true, $myrc4, $cache_to_file );
} else {
header( 'Location: ' . $pdfurl );
}
exit();
}
/**
* Helper Method to get secure
*
* @param string $pdfurl PDF Url.
* @return string
*/
public function get_secure_path( $pdfurl ) {
$upload_dir = wp_upload_dir();
$basedir = trailingslashit( $upload_dir['basedir'] ) . 'securepdfs/';
$baseurl = trailingslashit( set_url_scheme( $upload_dir['baseurl'] ) ) . 'securepdfs/';
$regex = '|^' . $baseurl . '(([^/]+/)*([^/]+\.pdf))$|';
$matches = array();
if ( preg_match( $regex, set_url_scheme( $pdfurl ), $matches ) ) {
// Check for .. tricks.
if ( ! preg_match( '|[\\\/]\.\.[\\\/]|', $pdfurl ) && strpos( $pdfurl, '\\' ) === false ) {
return $basedir . $matches[1];
}
}
return ''; // Wasn't a secure PDF.
}
/**
* Hash
*
* @var string
*/
protected $myrc4;
/**
* Read Chunk file
*
* @param string $file File.
* @param bool $retbytes Retbytes.
* @param bool $myrc4 RC4.
* @param string $cache_to_file file to cache.
* @return mixed
*/
protected function readfile_chunked( $file, $retbytes = true, $myrc4 = false, $cache_to_file = '' ) {
$chunksize = 1024 * 1024;
$buffer = '';
$cnt = 0;
$reading_from_cache = false;
$handle = false;
$cache_handle = false;
if ( '' !== $cache_to_file ) {
$cache_handle = @fopen( $cache_to_file, 'r' ); // @codingStandardsIgnoreLine
if ( false === $cache_handle ) {
$cache_handle = @fopen( $cache_to_file, 'w' ); // @codingStandardsIgnoreLine
} else {
// Read from cache.
$reading_from_cache = true;
$handle = $cache_handle;
$cache_handle = false;
}
}
$size = @filesize( $file ); // @codingStandardsIgnoreLine
if ( $reading_from_cache && @filesize( $cache_to_file ) != $size ) { // @codingStandardsIgnoreLine
// Revert back to non-cached version since can't be trusted.
error_log( 'Cached encrypted PDF was not of correct filesize: ' . $cache_to_file );
$handle = false;
$reading_from_cache = false;
$cache_handle = false;
}
if ( false === $handle ) {
$handle = @fopen( $file, 'r' ); // @codingStandardsIgnoreLine
}
if ( false === $handle ) {
return false;
}
if ( $size = @filesize( $file ) ) { // @codingStandardsIgnoreLine
header( 'Content-Length: ' . $size );
}
while ( ! @feof( $handle ) ) { // @codingStandardsIgnoreLine
$buffer = @fread( $handle, $chunksize ); // @codingStandardsIgnoreLine
if ( ! $reading_from_cache ) {
$buffer = $myrc4->rc4_encrypt_block( $buffer );
}
echo $buffer; // @codingStandardsIgnoreLine
if ( ! $reading_from_cache && false !== $cache_handle ) {
// Write to cache.
@fwrite( $cache_handle, $buffer ); // @codingStandardsIgnoreLine
}
if ( $retbytes ) {
$cnt += strlen( $buffer );
}
}
$status = @fclose( $handle ); // @codingStandardsIgnoreLine
if ( false !== $cache_handle ) {
@fclose( $cache_handle ); // @codingStandardsIgnoreLine
}
if ( $retbytes && $status ) {
return $cnt;
}
return $status;
}
/**
* Helper method for Secret Key
*
* @return string
*/
public function get_secret_key() {
$sk = get_site_option( 'pdfemb-sk' );
if ( false === $sk ) {
$sk = md5( sprintf( 'pdfemb-%d-%d', wp_rand(), time() ) );
update_site_option( 'pdfemb-sk', $sk, 60 * 60 * 12 );
}
return $sk;
}
/**
* Helper Method for Custom Upload Filter.
*
* @param string $file Upload File.
* @return string
*/
public function custom_upload_filter( $file ) {
if ( 'application/pdf' === $file['type'] && $this->pdfemb_secure ) {
add_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );
}
return $file;
}
/**
* Undocumented function
*
* @param string $function Function.
* @return bool
*/
protected function is_func_disabled( $function ) {
$disabled = explode( ',', ini_get( 'disable_functions' ) );
return in_array( $function, $disabled, true );
}
/**
* Undocumented function
*
* @param array $upload Upload.
* @return array
*/
public function custom_upload_dir( $upload ) {
// Override the year / month being based on the post publication date, if year/month organization is enabled.
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs.
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$upload['subdir'] = "/$y/$m";
}
$upload['subdir'] = '/securepdfs' . $upload['subdir'];
$upload['path'] = $upload['basedir'] . $upload['subdir'];
$upload['url'] = $upload['baseurl'] . $upload['subdir'];
return $upload;
}
/**
* Helper Method to create protected files
*
* @param bool $force Force Upload.
* @param string $method Protected method.
* @return void
*/
public function create_protection_files( $force = false, $method = false ) {
if ( false === get_transient( 'pdfemb_check_protection_files' ) || $force ) {
$wp_upload_dir = wp_upload_dir();
$upload_path = $wp_upload_dir['basedir'] . '/securepdfs';
wp_mkdir_p( $upload_path );
// Make sure the /edd folder is created.
wp_mkdir_p( $upload_path );
// Top level .htaccess file.
$rules = $this->get_htaccess_rules( $method );
if ( file_exists( $upload_path . '/.htaccess' ) ) {
$contents = @file_get_contents( $upload_path . '/.htaccess' ); // @codingStandardsIgnoreLine
if ( $contents !== $rules ) {
// Update the .htaccess rules if they don't match.
@file_put_contents( $upload_path . '/.htaccess', $rules ); // @codingStandardsIgnoreLine
}
} elseif ( wp_is_writable( $upload_path ) ) {
// Create the file if it doesn't exist.
@file_put_contents( $upload_path . '/.htaccess', $rules ); // @codingStandardsIgnoreLine
}
// Top level blank index.php.
if ( ! file_exists( $upload_path . '/index.php' ) && wp_is_writable( $upload_path ) ) {
@file_put_contents( $upload_path . '/index.php', '<?php' . PHP_EOL . '// This file is intentionally blank.' ); // @codingStandardsIgnoreLine
}
// Now place index.php files in all sub folders.
$folders = array();
$this->scan_folders( $upload_path, $folders );
foreach ( $folders as $folder ) {
// Create index.php, if it doesn't exist.
if ( ! file_exists( $folder . 'index.php' ) && wp_is_writable( $folder ) ) {
@file_put_contents( $folder . 'index.php', '<?php' . PHP_EOL . '// This file is intentionally blank.' ); // @codingStandardsIgnoreLine
}
}
// Check for the files every eight days.
set_transient( 'pdfemb_check_protection_files', true, 3600 * 24 * 8 );
}
}
/**
* Helper method to get htacess rules.
*
* @param string $method Protected Method.
* @return string
*/
protected function get_htaccess_rules( $method = false ) {
if ( empty( $method ) ) {
$method = 'direct';
}
switch ( $method ) {
case 'redirect':
// Prevent directory browsing.
$rules = 'Options -Indexes';
break;
case 'direct':
default:
$rules = "Options -Indexes\n";
$rules .= "<IfModule mod_version.c>\n";
$rules .= " <IfVersion < 2.4>\n";
$rules .= " Order Deny,Allow\n";
$rules .= " Deny from all\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Order Allow,Deny\n";
$rules .= " Allow from all\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfVersion>\n";
$rules .= " <IfVersion >= 2.4>\n";
$rules .= " Require all denied\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Require all granted\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfVersion>\n";
$rules .= "</IfModule>\n";
$rules .= "<IfModule !mod_version.c>\n";
$rules .= " <IfModule !mod_authz_core.c>\n";
$rules .= " Order Deny,Allow\n";
$rules .= " Deny from all\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Order Allow,Deny\n";
$rules .= " Allow from all\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfModule>\n";
$rules .= " <IfModule mod_authz_core.c>\n";
$rules .= " Require all denied\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Require all granted\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfModule>\n";
$rules .= "</IfModule>\n";
break;
}
return $rules;
}
/**
* Helper Method to scan folders
*
* @param string $path Path.
* @param string $return Return Path.
* @return void
*/
protected function scan_folders( $path, &$return ) {
$lists = @scandir( $path ); // @codingStandardsIgnoreLine
if ( ! empty( $lists ) ) {
foreach ( $lists as $f ) {
if ( is_dir( $path . DIRECTORY_SEPARATOR . $f ) && '.' !== $f && '..' !== $f ) {
$finaldirpath = trailingslashit( $path . DIRECTORY_SEPARATOR . $f );
if ( ! in_array( $finaldirpath, $return, true ) ) {
$return[] = $finaldirpath;
}
$this->scan_folders( $path . DIRECTORY_SEPARATOR . $f, $return );
}
}
}
}
}