Is it advisable to utilize jQuery's parseJSON/getJSON functions?

Upon examining the jQuery parseJSON function, I discovered that it essentially performs a basic regex validation:

parseJSON: function( data ) {
    if ( typeof data !== "string" || !data ) {
        return null;
    }

    // Remove leading/trailing whitespace to accommodate IE limitations
    data = jQuery.trim( data );

    // Validate incoming data as JSON
    // Adapted from http://json.org/json2.js
    if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
        .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {

        // Attempt to use native JSON parser for modern browsers
        return window.JSON && window.JSON.parse ?
            window.JSON.parse( data ) :
            (new Function("return " + data))();

    } else {
        jQuery.error( "Invalid JSON: " + data );
    }
},

If the check passes and if the browser is current, it utilizes the native JSON parser. In the case of older browsers like IE6, a new function is employed to return the object.

Question #1: Given that this method relies on a straightforward regex test, could it potentially be vulnerable to obscure edge-case exploits? Would it be wiser to implement a comprehensive parser, especially for browsers lacking native JSON support?

Question #2: How secure is

(new Function(" return " + data ))()
compared to eval("(" + text + ")")?

Answer №1

It's worth noting that jQuery's JSON parser incorporates the logic from json2.js to verify the validity of a JSON string, making it as secure as other commonly used non-native parsers which are already quite strict:

// The second stage involves running regular expressions to detect non-JSON patterns such as '()' and 'new' 
// that could lead to function invocation or assignment,
// amongst others.
// Despite its inefficiency, we break this process into 4 steps due to limitations in IE and Safari's regex engines. 
// We first replace JSON backslash pairs with '@', 
// then tokenize simple values to ']'. Next, we eliminate open brackets following a colon, comma, or at the start of the text. Finally, 
// we ensure the remaining characters consist only of whitespace, ']', ',', ':', '{', or '}'. If so, the text is deemed safe for eval.

if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

I find it puzzling why jQuery performs regex operations before checking for a native implementation to validate JSON grammar since using a native approach could potentially boost performance if available.

Another query similar to question 2 has been addressed effectively by bobince on Stack Overflow:

In terms of language quirks rather than security concerns, there's a slight preference for new Function over eval. Although both are equally unreliable with untrusted input, assuming your web app doesn't encounter untrustworthy JSON strings. This distinction affects how well optimizations can be applied.

For further insights, read an excerpt from John Resig presented in Nick Craver's response.

Answer №2

For secure JSON parsing, it is recommended to utilize the JSON.parse method. By including the script json2.js from http://www.json.org/js.html, this method becomes accessible and is automatically integrated with functions like parseJSON/getJSON. Instead of directly executing JSON data, it efficiently parses the markup.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to combine JSON objects from a two-dimensional array into a single array using JavaScript?

I have a JSON object within an array that I want to push to an employeeArray. employeeArray =[ [ { "ID":"967", "NAME":"Dang, Lance D", "Email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0e426f6 ...

"Enhance your webpage with a captivating opaque background image using Bootstrap

I'm new to exploring Bootstrap and I am currently experimenting with options for displaying content with a semi-transparent background image. Currently, I am using a "well" but I am open to other suggestions. I have managed to place the image inside t ...

Exploring the functionality of two-way data binding in Angular - a beginner's guide

Transitioning from a different framework and switching from JavaScript to Angular & TypeScript has left me feeling confused about how to efficiently share data/values between components. ...

Is there a way to dynamically set a database path in Express.js depending on the user's login status?

I have a backend service that serves as the primary entry point for my web application, where I want to dynamically allocate a database path based on user login. While I understand that this solution may not be scalable in the long run, I plan to use it fo ...

What mechanism does package.json use to determine whether you are currently operating in development or production mode?

What is the process for package_json to determine when to load devDependencies as opposed to regular dependencies? How does it differentiate between local development and production environments? ...

Experiencing issues with utilizing long polling on a node.js server URL in Internet Explorer

Currently, I am in the process of testing an application that utilizes long polling with jQuery to query a server built with node.js. The code for long polling is as follows: (function poll(){ $.ajax({ url: "http://localhost:3000/test", ...

The dimensions of the cards adjust automatically when the flex direction is set to row

My cards, created in CSS and React.js, have a set height and width. However, when I change the flex direction from column to row, the cards automatically shrink in size. Why is this happening? Card's CSS and JS code CSS .card{ height: 50%; w ...

Having trouble retrieving response headers in Angular 5

After sending a post request to a server, I receive a response with two crucial headers for the client: username and access-token. The Chrome debug tool's Network Tab displays the data from the response like this: https://i.sstatic.net/XN9iv.png In ...

Adding data to a database table using Python

As a newcomer to Python, I am working on a project that involves classifying tweets into different categories. I have set up a tweet table in a MySQL database with the following attributes: (tweet_id, id_user, text, tweet_location, created_at, name_screen, ...

Error: Unable to access the 'wsname' property of an undefined value

I am attempting to retrieve values from a database using the code below (login.js) $.post("http://awebsite.com/app/login.php",{ rep1: rep, password1:password}, function(data) { if(data=='Invalid rep.......') { $('input[type="text"]').c ...

What is the best way to identify duplicate IDs within an array?

function fetchTweets($query){ $url = "http://search.twitter.com/search.json?q=".$query."&include_entities=true&result_type=mixed"; $content = file_get_contents($url); $tweetsArray = json_decode($content, true); foreach($tweetsArray ...

Send a bundle of data through AJAX requests

An issue has been encountered on an HTML/PHP page named sucessful.php where a variable job_id passed from another page is not being received by the destination page interview.php. The problem arises when attempting to transfer two variables and their corr ...

Struggling to properly reference an item within an array

Struggling to create an HTML page for a class project that utilizes a drop-down menu to display relevant information from an array? Check out my jsfiddle for the full HTML section. Any assistance would be greatly appreciated. I must admit, I'm not we ...

Generate a table framework by dynamically adjusting the number of rows and columns

I'm running into an issue with my implementation of nested for-loops to dynamically generate a table using JavaScript. For this particular scenario, let's assume numRows = 2 and numCols = 6. This is the code snippet in question: let table = $( ...

Oops! It seems that an invalid BCrypt hash triggered an unspecified "error" event that was not handled

Attempting to develop an API for login in nodejs. However, when checking the login route via HTTP requester, nothing is displayed in the output. Instead, the command line shows an error Error: Uncaught, unspecified "error" event. (Not a valid BCrypt hash.) ...

An issue has arisen when trying to fetch and parse data using React and JavaScript

I am currently facing some challenges with fetching data from an API and displaying it using React. I have encountered errors and I am struggling with parsing the JSON response from the API. I believe that converting the response into an array may help res ...

Add unique content to a div upon page reload

Whenever the page is refreshed, I would like to add a random anchor from an array into a specific div. Here's my current code: <div id="exit-offer" class="exit-offer-dialog"> <div class="offer-content" id="banner-load"> <bu ...

Can you provide guidance on displaying flash messages in my template using Express.js?

app.get('/',function(req,res){ res.render('home'); // Ensure the template has access to the flash message }); app.get('/go',function(req,res){ req.flash("info", "You have gone to GO and got redirected back home!"); ...

jQuery AJAX POST Request Fails to SendIt seems that the

The issue I am experiencing seems to be directly related to the jQuery $.ajax({...}); function. In PHP, when I print the array, I receive a Notice: Undefined index. I would greatly appreciate any advice or guidance on this matter. <script> $(docume ...

Different results can be observed when comparing the array ordering in JavaScript between IE8 and Chrome

The array presented with items listed in specific order: { "5":{ "Title":"Title A", "Desc":"Description A" }, "15":{ "Title":"Title B", "Desc":"Description B" }, "10":{ "Title":"Title C", "Desc":"Description C ...