]> source.dussan.org Git - jquery-ui.git/commitdiff
Widget: Don't let widget name affect `$.ui` prototype & constructor
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Wed, 30 Oct 2024 08:58:01 +0000 (09:58 +0100)
committerGitHub <noreply@github.com>
Wed, 30 Oct 2024 08:58:01 +0000 (09:58 +0100)
This is an edge case and it only affects code accepting untrusted input as
a widget name, but it's still technically correct to filter these out.

Closes gh-2310

tests/unit/widget/core.js
ui/widget.js

index fe74e18e94e0f9eeb78349f98a844b23e933dfe3..38e63a8c0571d98b5674f5b85bfc68c5fc03531d 100644 (file)
@@ -242,6 +242,28 @@ QUnit.test( "error handling", function( assert ) {
        $.error = error;
 } );
 
+QUnit.test( "Prototype pollution", function( assert ) {
+       assert.expect( 3 );
+
+       var elem = $( "<div>" );
+
+       $.widget( "ui.testWidget", {} );
+
+       elem.testWidget();
+
+       try {
+               $.widget( "ui.__proto__", {} );
+       } catch ( _e ) {}
+       try {
+               $.widget( "ui.constructor", {} );
+       } catch ( _e ) {}
+
+       assert.strictEqual( Object.getPrototypeOf( $.ui ), Object.prototype,
+               "$.ui constructor not modified" );
+       assert.ok( $.ui instanceof Object, "$.ui is an Object instance" );
+       assert.notOk( $.ui instanceof Function, "$.ui is not a Function instance" );
+} );
+
 QUnit.test( "merge multiple option arguments", function( assert ) {
        assert.expect( 1 );
        $.widget( "ui.testWidget", {
index 7201b4fbf6324200af2fc41826831cfcf62f7eae..d5fbd885cf0c6a589488dd6e650579db608a6ebf 100644 (file)
@@ -56,6 +56,9 @@ $.widget = function( name, base, prototype ) {
 
        var namespace = name.split( "." )[ 0 ];
        name = name.split( "." )[ 1 ];
+       if ( name === "__proto__" || name === "constructor" ) {
+               return $.error( "Invalid widget name: " + name );
+       }
        var fullName = namespace + "-" + name;
 
        if ( !prototype ) {