Skip to content

Instantly share code, notes, and snippets.

@Sudistark
Last active January 14, 2024 01:37
Show Gist options
  • Save Sudistark/d869e505c8ff45c3bb96612bcb2c953b to your computer and use it in GitHub Desktop.
Save Sudistark/d869e505c8ff45c3bb96612bcb2c953b to your computer and use it in GitHub Desktop.

I was trying to find a pp gadget in jquery and stumble upon this, is there any way to force hooks = jQuery.attrHooks[ name.toLowerCase() ] not use the polluted property

Below you will find details for what I am relating to:

$("#homepage").attr({
                    "src": "https://google.com",
                    "hidden": false
});

By polluting

x={}
x.__proto__.srcdoc="<img src=x onerror=alert()>"

This key object contains this srcdoc property also https://github.com/jquery/jquery/blob/937923d9ee8dfd19008447b5059cbd13ee5a23ac/src/core/access.js#L14

    // Sets many values
    if ( toType( key ) === "object" ) {
        chainable = true;
        for ( i in key ) {
            access( elems, fn, i, key[ i ], true, emptyGet, raw );
        }

Later, name-> srcdoc value -> <img src=x onerror=alert()>

https://github.com/jquery/jquery/blob/937923d9ee8dfd19008447b5059cbd13ee5a23ac/src/attributes/attr.js#L19

jQuery.extend( {
    attr: function( elem, name, value ) {
        var ret, hooks,
            nType = elem.nodeType;

        // Don't get/set attributes on text, comment and attribute nodes
        if ( nType === 3 || nType === 8 || nType === 2 ) {
            return;
        }

        // Fallback to prop when attributes are not supported
        if ( typeof elem.getAttribute === "undefined" ) {
            return jQuery.prop( elem, name, value );
        }

        // Attribute hooks are determined by the lowercase version
        // Grab necessary hook if one is defined
        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
            hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
                ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
        }

        if ( value !== undefined ) {
            if ( value === null ) {
                jQuery.removeAttr( elem, name );
                return;
            }

            if ( hooks && "set" in hooks && // error trigger here
                ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                return ret;
            }

            elem.setAttribute( name, value + "" ); // here is the sink
            return value;
        }

Due to the polluted srcdoc property, instead of returning undefined for hooks it returns a string (polluted string)

hooks = jQuery.attrHooks[ name.toLowerCase() ]
attrHooks is an object so 

jQuery.attrHooks["srcdoc"] -> returns a string

And when "set" in hooks is executed inside the if statement, it triggers this error and I can no longer reach the sink

Uncaught TypeError: Cannot use 'in' operator to search for 'set' in <img src=x onerror=alert()>
@codecracker007
Copy link

Why dont You Try Adding the Attributes in UpperCase?

jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { jQuery.attrHooks[ name ] = { get: function( elem ) {
Since it matches with case sensitive jQuery.attrHooks[ name.toLowerCase() ] Should return undefined in this case? might be wrong tho just a hunch

@Sudistark
Copy link
Author

Wait this is private how the fuck did you get the link?

Yeah I already figured that uppercase one was the solution indeed plus you can do something like this also
[srcdoc][]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment