• Resolved axew3

    (@axewww)


    So i am on the way to release a nice plugin, but there is a problem, that’s in reality not a problem due to how filenames are managed server side, anyway, do you know another way to workaround this?

    There is NO way to pass the correct content if it is passed using the common WP ways.

    I installed the validator plugin to check, but really this cannot be solved in different way, and as said it is anyway absolutely safe, so to you it will be ok?

    PS it is anyway OK also because all the encryption and decryption processes happen into the Browser.

    The server never see real data and anyone that could download the file, will not do too much with, without owning the ML-KEM 1024 Private key

    public function get_encrypted_content( $request ) {
    $filename = sanitize_file_name($request->get_param('file'));
    $token = sanitize_text_field($request->get_param('key'));
    $saved_token = get_option( 'w3token_' . $filename );

    if ( $saved_token && $saved_token === $token ) {
    $upload_dir = wp_upload_dir();
    $file_path = $upload_dir['basedir'] . '/w3mypgp_vault/' . $filename;

    // Could be used js fetch on frontend but why? It is not reliable
    // return new WP_REST_Response( array( 'success' => true, 'message' => $filename ), 200 );

    if ( file_exists($file_path) ) {


    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($file_path));

    if (ob_get_level()) ob_end_clean();


    /* // THIS DO NOT WILL WORK

    require_once ABSPATH . 'wp-admin/includes/file.php';

    if ( WP_Filesystem() && file_exists($file_path) ) {
    global $wp_filesystem;

    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($file_path));

    if (ob_get_level()) ob_end_clean();

    // NOTE: wp_kses_post corrupt bits and make it fail the decryption
    // wp_kses_post cannot be used

    // $content = $wp_filesystem->get_contents( $file_path );
    // echo wp_kses_post( $content ); # fail
    // echo $content; # Ok. but maybe not safe

    }*/

    /* This way works and it's safe. The file path is the one stored and cannot be otherwise

    Input Validation: Since we used sanitize_file_name, a hacker cannot request ../../wp-config.php. They can only request files inside our vault.
    Token Check: the code already checks if the $token matches. Only someone with the correct link can trigger the stream.

    Conclusion: Don't try to sanitize the binary bits. The output is a binary ciphertext for Post-Quantum decryption (ML-KEM); sanitizing the output would corrupt the cryptographic integrity.
    */

    $fp = fopen($file_path, 'rb');
    fpassthru($fp);
    fclose($fp);

    // readfile also works
    // Dump the file bits to the network stream
    // readfile($file_path);

    // SELF-DESTRUCT
    // unlink($file_path);
    // delete_option('w3token_' . $filename);

    // STOP HERE. Do not let WordPress send out any more data.
    exit;
    }

    // Only if the file/token is wrong return a standard error
    return new WP_Error('fail', 'Invalid link.', array('status' => 404));
    }
    }
    • This topic was modified 1 month ago by axew3.
    • This topic was modified 1 month ago by axew3.
Viewing 7 replies - 1 through 7 (of 7 total)
  • Moderator threadi

    (@threadi)

    I understand your frustration here. I’ve been there myself. In one of my plugins, I return files in a similar way – mostly images, but also PDFs.

    It’s important to note that you shouldn’t use PHP’s built-in functions to read and output the files. WordPress provides WP_Filesystem for this purpose: https://developer.ww.wp.xz.cn/reference/functions/wp_filesystem/

    In my case, I use this (simplified) code, for example:

    require_once ABSPATH . '/wp-admin/includes/file.php'; // @phpstan-ignore requireOnce.fileNotFound
    require_once ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php'; // @phpstan-ignore requireOnce.fileNotFound
    require_once ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php'; // @phpstan-ignore requireOnce.fileNotFound
    \WP_Filesystem();
    global $wp_filesystem;

    // return header.
    header( 'Content-Type: ' . $mime_type );
    header( 'Content-Disposition: inline; filename="' . $filename . '"' );
    header( 'Content-Length: ' . wp_filesize( $file ) );

    // return file content via WP filesystem.
    echo $wp_filesystem->get_contents( $file ); // phpcs:ignore WordPress.Security.EscapeOutput
    exit;

    Maybe this will help you with your situation.

    Thread Starter axew3

    (@axewww)

    It worked. You magic!

    Going to submit the plugin asap! There is some minor warning about not used nonces, i will check to fix also this aspect.

    Thank You!

    Ps the plugin use hard front end javascript, alerting some message into some task. Is there a way to pass those vars so to be translated like on php example esc_html_e(“Public ML-DSA
    (Sign) Key”, “w3mypgp”)

    or it need to be injected from php (hope it is clear what i mean) the translated phrase?

    • This reply was modified 1 month ago by axew3.
    Moderator threadi

    (@threadi)

    Great that you were able to adapt this for your needs. It took me a while to figure it out back then, but this is a perfectly logical and reliable way to serve files.

    Texts that are output via JavaScript can be made translatable in WordPress in various ways:

    The simplest method is probably wp_localize_script(). With this function, you pass a JavaScript object containing the text to be translated to a script handler. You can find examples in the linked manual.

    Another approach would be to embed the translation directly into JavaScript using __(). To do this, you need to import WordPress’s own JavaScript package into your JavaScript:

    import {__} from "@wordpress/i18n";

    This, in turn, requires that you generate your scripts. See: https://learn.ww.wp.xz.cn/tutorial/installing-node-js-and-npm-for-local-wordpress-development/

    For texts that are displayed after an AJAX request, I now take a completely different approach. I include the texts in the AJAX response and then display them. This allows the translation to remain entirely in PHP.

    Thread Starter axew3

    (@axewww)

    Great thank You!

    I will return back with a link.

    Think i will release without fixing the multilang, only Eng on version 1.0. Next release will fix this.

    Can’t wait anymore, You know the world require to be safe immediately! ahaha

    Thread Starter axew3

    (@axewww)

    Hello threadi! w3mypgp plugin have been submitted to the plugin repo at wp.org. The world cannot wait to be safe 😅 anyway there are 466 plugins in queue so or i will publish into github or into the site just a download link, or we have to wait do not know how much before to see it released! 😭

    It was a dead domain registered that i own since 2003 so it will be dedicated to the security online the w3mypgp plugin for WP and various html/js tools (standalone html files containing encryption libraries as worker modules within) for a security online that’s quite different from others. There are no possible traps, there are no known bugs.

    There is no way (or let say, it is quite impossible) to fuck things like these (all natively processed inside the browser)

    👉 [self promotion link redacted]

    • This reply was modified 4 weeks ago by axew3.
    • This reply was modified 4 weeks ago by bcworkz. Reason: promotion link redacted
    Moderator bcworkz

    (@bcworkz)

    @axewww — Your self promoting link has been redacted because it runs afoul of our forum guidelines. I’m glad you’re excited about your plugin and I encourage you to promote it, but this is not the place for that. There’s probably enough context in the rest of your post for someone to be able to locate your site if they were so inclined.

    Thread Starter axew3

    (@axewww)

    Forgive me my intent was to promote nothing but just to show to who helped me to fix an hard issue, a result.

    I could had it on slack? Maybe. Or where? Anyway ok!

    threadi, you’ll be mentioned into the w3mypgp code, into the file

    /wp-w3mypgp.php file.

    I will return back informing when finally, after a very hard effort, the plugin that accomplish now to all guidelines, has been published.

    • This reply was modified 2 weeks ago by axew3.
    • This reply was modified 2 weeks ago by axew3.
Viewing 7 replies - 1 through 7 (of 7 total)

You must be logged in to reply to this topic.