15

THE ISSUE

I used to be able to (locally) use either of the following two Chrome extensions to easily inject jQuery into pages that didn't already have jQuery, and that I didn't own (client-side) to experiment with design changes, development modifications, and real-time troubleshooting:

Unfortunately, now because of what appears to be the newest craze in preventing "XSS" (cross-site scripting), those plugins no longer work. There may be a noble purpose behind these changes, and I'm just trying to understand WHAT changed. I think it has something to do with "content security policy", which I've only recently heard of and have very little knowledge of.

I first learned about XSS as a browser issue in 2011, however, XSS prevention measures had never prevented me from doing local development before. I've been searching for a modern (late 2017) solution, to no avail.

I'm not sure where to go from here.

WHAT I'VE TRIED THAT HASN'T WORKED

Here are plugins I tried (which used to work until about 6 months ago) that no longer work for me:

  1. jQuery in Console (Plugin)
  2. jQuery Inject (Plugin)
  3. jQuery Injector (Plugin)
  4. GitHub - bluerabbit/jquery-inject: jQuery-inject(Chrome extension)

Here are some of the many links I encountered that offer solutions which no longer work:

This last one also looks promising, but I haven't tried it yet:

MY QUESTIONS

  1. How can I inject jQuery (using Chrome Developer Console) into a webpage that doesn't use jQuery?

  2. Did something change in the browser/JavaScript/programming world significantly enough in 2017 that if a person knew about this particular change or phenomena it would easily explain why the above plugins no longer work?

  3. Why don't the above plugins work? Did ALL the browser companies universally roll out some major change this year?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • can you tell me why you need to inject the jquery? i means for what purpose? #wantToKnow – plonknimbuzz Dec 27 '17 at 18:44
  • I have just tested one of the plugins that you posted and it works just fine: https://chrome.google.com/webstore/detail/jquery-inject/iibfbhlfimdnkinkcenncoeejnmpemof?hl=en-US – Ahmed Musallam Dec 27 '17 at 18:47
  • i work fine with your reference https://stackoverflow.com/questions/7474354/include-jquery-in-the-javascript-console . i didnt try the rest, because this works for me – plonknimbuzz Dec 27 '17 at 18:49
  • @plonknimbuzz I already explained that here: `(client-side) to experiment with design changes, development modifications, and real-time troubleshooting` – Eric Hepperle - CodeSlayer2010 Dec 27 '17 at 18:50
  • @plonknimbuzz Hmm. I already cleared cache and such, ... given that you are having success, I will test again and will update if I have errors still. Thanks! – Eric Hepperle - CodeSlayer2010 Dec 27 '17 at 18:51
  • @AhmedMusallam Ok, thanks for verifying that it works for you! I will try it again and see if I am still having problems. I suspect I will be, but since I know somebody else is not having the same issue, that will help me to focus my troubleshooting. – Eric Hepperle - CodeSlayer2010 Dec 27 '17 at 18:53
  • make sure your browser is not injected with any script from adware, addons or your ISP connection. i really have experience with this. make simple script. check your DOM and your source. – plonknimbuzz Dec 27 '17 at 18:53
  • 1
    @plonknimbuzz Thanks. I will look into those factors. I tried to update my comment about the "why" above, but it didn't take so here is the rest of my response.: `From time to time I will run across old, basic websites and using jQuery I can quickly mock up what an upgrade might look like for the owner who, as a freelance web developer/designer, I am hoping to make my client.` Hope that helps. – Eric Hepperle - CodeSlayer2010 Dec 27 '17 at 18:57
  • did you already solve your problem yet? for your reason: yes thats make sense, because i did it too when i want to send my client fast demo. ex: i want use premium template which i will buy only if my client deal with me, if not i wont buy. i always use webconsole to edit, dom, css and overide js whenever its possible. the different thing is, all my target already have jquery. – plonknimbuzz Dec 28 '17 at 05:31
  • @plonknimbuzz Did I solve the problem? Yes and no: I have not learned how to make jQuery work again, but I taught myself ES6 and rewrote all my jQuery code to use that instead. Now I have less dependency issues and everything still works. :) What I need to do next is learn how create my own javascript libarary and import it into Chrome. Maybe that will best be through a plugin? – Eric Hepperle - CodeSlayer2010 Feb 08 '18 at 21:59

5 Answers5

23

Here is a direct method that has always worked for me:

var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);

// ... give time for script to load, then type (or see below for non wait option)
jQuery.noConflict();

Just paste each line into the console, one at a time. (Actually, it works fine if you select the lines and paste them into DevTools Console all-at-once).

You might immediately see an error: Uncaught ReferenceError: jQuery is not defined. Ignore it - DevTools is pulling your leg. (Google's weak attempt at humor, maybe...)

Then, in DevTools console, test it:

$('div').length; //press Enter

If you get an error, try it this way:

jQuery('div').length

Hopefully, the first will work - but sometimes you'll need to use the second method.

This code is thanks to jondavidjohn, from this original post.

cssyphus
  • 37,875
  • 18
  • 96
  • 111
7

Use Snippets.

  1. Copy the jQuery code, and paste it into a Snippet.
  2. Run the Snippet.
Kayce Basques
  • 23,849
  • 11
  • 86
  • 120
  • 1
    Works (*in Google Chrome Version 83.0.4103.116*) like a charm! It avoids [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) issues. – stomy Jun 30 '20 at 23:37
3

Unfortunately, now because of what appears to be the newest craze in preventing "XSS" (cross-site scripting), those plugins no longer work. There may be a noble purpose behind these changes, and I'm just trying to understand WHAT changed. I think it has something to do with "content security policy", which I've only recently heard of and have very little knowledge of.

Yes. The reason why these plugins don't work is because they're indistinguishable from MITM (man-in-the-middle) attacks where malicious attackers can inject arbitrary JavaScript. CSP (Content-Security-Policy) is designed to prevent this from happening by only running trusted JavaScript from a whitelist of sources. Unfortunately, there's currently no easy way to deal with this in either Chrome or Firefox until the developers whitelist injected JavaScript/CSS from plugin authors. This is unlikely to happen since Chrome has a guide for app developers on how to comply with the CSP policy.

In the meanwhile, I recommend you get caught up on the OWASP article's on XSS so you can learn why it is so important.

Not recommended approach

You can download the "Disable Content-Security-Policy" addon from the Chrome store. Use this only for local development. Keep in mind if you do this, a malicious ISP or dedicated attacker can still inject scripts in a MITM attack (if they have control of your router for example).

Recommended approach

Don't inject jQuery, but put it in your page. Add a CSP tag:

<meta http-equiv="Content-Security-Policy" content="...">

Here you would put something like default-src 'self'; script-src https://cdn.com/jquery where cdn.com is where you're downloading jQuery from. Go one step further and add a subresource integrity hash. If the CDN ever gets compromised, becomes malicious, or you become MITM'd, the hash will not match and the malicious script won't be loaded. Furthermore, you can never really trust addons for the same reason.

If you decide not to use a CDN, you can use a package manager (like node or Bower) that will download a specific version of jQuery for you. Then just load it locally. Of course for production, you generally want to be using the CDN so that your visitors can download from a closer data-center. Also if you are using Cloudflare, it's likely that they'll have cached that specific version of jQuery, so they don't have to keep downloading it.

Prototyping

If your motivation is prototyping, then there are workarounds:

Not recommended: You can scrape the website, do your modifications, and then present to the client.

Recommended: Instead of doing modifications on a live website, you should be doing rapid prototyping. The advantages of this are:

  • If you are doing a sitdown with the client, the client can see exactly what you're doing

  • You are dealing with abstract prototypes and not concrete details, which should be laid down in the contract. See ux.stackexchange.com for questions on skeleton screens.

  • You can explain to the client why you cannot do X (inject jQuery into live sites) when you should be doing Y (see rest of answer) which will hopefully convince them to adopt better security practices

  • The prototypes can be stood up and quickly thrown away, and you can even keep revisions around for comparison purposes. Changes to a live site don't make this easy

  • Thanks for the detailed info! You have opened my eyes to many things I was not aware of. The csp meta tag, rapid prototyping, MITM attacks, etc. I was able to workaround the inject jQuery issue by learning the modern ES6 JavaScript `document.querySelectorAll()` method, thereby not needing jQuery, and making what I've always called snippets (which may or may not be the same as what Chrome Dev Tools is calling snippets) to run in the console. I just converted all my jQuery snippets to ES6. However, I am looking forward to investigating the new concepts you presented further :) – Eric Hepperle - CodeSlayer2010 Dec 30 '17 at 17:58
1

You can make a very basic chrome extension which just injects JQuery on every page. Getting started with chrome extensions. You can specify that in the manifest itself using this piece of code.

"content_scripts": [
     {
          "matches": ["*"],
          "js": ["jquery.min.js"]  }
]

Note that the * in matches will inject the script on every web page. You can give different patterns too. Example, "www.abc.com/*" will match all the URLs starting with "www.abc.com" and will inject the script on such pages only.

Better Solution

Something even better will be to create a chrome extension that can inject your JavaScript file in the current tab when ever you click on the extension icon.

Make a background script and specify it in your manifest.

manifest.json

{
  "name": "My Extension",
  "version": "0.1",
  "manifest_version": 2,
  "description": "inject script",
  "browser_action": {
    "default_icon": "logo.png"
  },
  "permissions": [
    "activeTab"
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

In your background script, listen for clicks on the extension icon and inject jquery in the currert tab.

background.js

chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.executeScript(null, {file: "jquery.min.js"});
});
-4

Simplest way is to execute this in the dev console as a whole and see the magic:

var script = document.createElement('script');
script.src = "https://code.jquery.com/jquery 3.4.1.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
Shoaib Khalil
  • 1,874
  • 17
  • 10
  • **This answer is exactly identical to the previous answer (posted two years earlier), except with the variable names changed.** -1 – crashwap Dec 21 '21 at 17:39