Twitter Show Sensitive Content

No more extra click to show stupid tweets!

< Feedback on Twitter Show Sensitive Content

Question/comment

§
Posted: 26-09-2022

[Violentmonkey] To bypass Firefox CSP, need to add additional metadata `inject-into` tag:
https://violentmonkey.github.io/posts/inject-into-context/
https://violentmonkey.github.io/api/metadata-block/#inject-into

§
Posted: 28-09-2022

I had no idea that the script stop working with Violentmonkey...

Note that adding inject-into tag will not make it work magically; I will see if I can fix it on content mode, as page seem to be broken on Firefox

§
Posted: 20-11-2022
Edited: 20-11-2022

Sorry for the huge delay of my response.

I managed to make a "working" script for Violentmonkey that works on content mode using the wrappedJSObject and exportFunc, BUT I stunned into other limitation of the extension/MOZ Extension API that, as far as I know, only affects XMLHttpRequest.prototype (and most probably WebSockets). This "limitation" prevents modifying the response.

I cannot do anything for this, the only workaround is using other extension just to disable the Content Security Policy for Twitter.

There's no point in uploading that script version, as I does not work and Tampermonkey just disabled the compatibility support for wrappedJSObject by default a few days before this message.

But for the record, I'll leave the userscript here:

//* eslint-env browser, es6, greasemonkey */
// ==UserScript==
// @name         DEV: Twitter Show Sensitive Content
// @namespace    kTu*Kzukf&5p#85%xas!fBH4#GT@FQ7@
// @version      0.3.5
// @description  No more extra click to show stupid tweets!
// @author       _SUDO
// @match        *://*.twitter.com/*
// @icon         https://www.google.com/s2/favicons?domain=twitter.com
// @license      GPL
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// @inject-into  content
// ==/UserScript==

;(function () {
    'use strict'

    // See: https://github.com/violentmonkey/violentmonkey/issues/1028#issuecomment-681352072
    // See: https://github.com/violentmonkey/violentmonkey/issues/1001
    // See: https://stackoverflow.com/questions/9515704/access-variables-and-functions-defined-in-page-context-using-a-content-script/9517879#9517879

    // See: https://github.com/ilinsky/xmlhttprequest/blob/master/XMLHttpRequest.js
    // SEE: https://github.com/AlttiRi/gm_fetch/blob/57063c4dd79614a76ad6ca263c600c31fb9fca84/demo-dev.user.js#L409

    var _window
    try {
        // This window refers to the "page window" on content mode or just "unsafeWindow"
        const thisWindow = typeof unsafeWindow === 'object' ? unsafeWindow : window
        _window = typeof thisWindow.wrappedJSObject === 'object' ? thisWindow.wrappedJSObject : thisWindow

    } catch (err) {
        console.error('[userscript] Error trying to get window object\n', err)
    }


    console.log('[userscript] Is running on content mode?', typeof _window.wrappedJSObject === 'object')
    console.log('[userscript] Is exportFunction supported?',typeof exportFunction === 'function')

    // Creates and caches a random string to replace later the possibly_sensitive object key
    const ranString = (() => Array(5).fill().map(() => 'abcdefghijklmnopqrstuvwxyz'.charAt(Math.random() * 62)).join(''))()

    // Content script wrapper for Violentmonkey
    const exportFunc =/*GM_info.scriptHandler === 'Violentmonkey' && */ typeof exportFunction ==='function' ? exportFunction : (fn) => fn

    // Save original prototype
    const org_prototype = exportFunc(
        _window.XMLHttpRequest.prototype.open,
        _window
    )

    const intercept_pattern = /i\/api\/.+\/User|TweetDetail|Adaptive/gi // 179 steps, 0.01ms

    const intercept_response = (response, responseURL) => {
        console.log('[API] FOUND RESPONSE!\n', responseURL, response)

        const new_response = response
            .replace(/sensitive_media/gim, '')
            .replace(/possibly_sensitive/gim, ranString)
            .replace(/offensive_profile_content/gim, '')

        return new_response
    }

    function open_proto() {
        if (arguments['1'].match(intercept_pattern)) {
            this.addEventListener('readystatechange', function (event) {
                if (this.readyState === 4) {
                    const response = intercept_response(
                        event.target.responseText,
                        event.target.responseURL
                    )
                    Object.defineProperty(this, 'response', { writable: true })
                    Object.defineProperty(this, 'responseText', { writable: true })
                    this.response = this.responseText = response
                }
            })
        }

        // Slice an empty array to prevent errors when passing empty values
        return org_prototype.apply(this, [].slice.call(arguments))
    }

    // Inject hijacked API
    _window.XMLHttpRequest.prototype.open = exportFunc(open_proto, _window)
})()
§
Posted: 06-01-2023

>the only workaround is using other extension just to disable the Content Security Policy for Twitter.
What a bummer, only Tampermonkey addon can modify CSP policies. Thanks for your effort anyway.

Post reply

Sign in to post a reply.