I need to inject some JavaScript into an existing application.
The application is normally embedded with an iframe like this:
<html>
<body>
<iframe src="http://webchat.quakenet.org/" width="647" height="400"></iframe>
</body>
</html>
It is an opensource JavaScript based IRC Client http://webchat.quakenet.org/ (source).
Now I like to inject some JS to Highlight special messages for example. For this I already found the HilighterClass to override.
The problem is, how could I do that? I guess injecting JS into an iFrame is not "allowed" by modern browsers, or?
If the iFrame is a problem, maybe I can add the client like they do:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<base />
<title>QuakeNet Web IRC (qwebirc)</title>
...
<script type="text/javascript">
var ui = new qwebirc.ui.Interface("ircui", qwebirc.ui.QUI, {"appTitle":"QuakeNet Web IRC","dynamicBaseURL":"/dynamic/leibniz/","baseURL":"http://webchat.quakenet.org/","validateNickname":false,"networkServices":["Q!TheQBot#CServe.quakenet.org"],"nickValidation": {"maxLen":15,"validSubChars":"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_[]{}`^\\|0123456789-","validFirstChar":"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_[]{}`^\\|","minLen":2},"staticBaseURL":"/static/leibniz/","loginRegex":"^You are now logged in as [^ ]+\\.$","networkName":"QuakeNet"});
</script>
</head>
<body>
<div id="ircui">
<noscript>
<div id="noscript">Javascript is required to use IRC.</div>
</noscript>
</div>
</body>
</html>
Requirements:
The client should connect into the quakenet.org Servers. That could be a problem because of some Cross-Site-Scripting restrictions.
The best would be if no other plugin's for my users are required.
You could a Proxy server like Privoxy which can inject JavaScript into pages. Unfortunately your users would have to do all their browsing through Privoxy, so that might not be an option.
Or you set up your own reverse proxy (e.g. Squid) and change the contents before relaying. You'd replace the requests to the JavaScript library with a call to your own library which contains the original JavaScript plus your highlighting code.
Ans surely you heard of Greasemonkey, which is a browser plugin which can do exactly that - inject content.
you cannot manipulate the contents of an iframe. cross site scripting is not the problem here.
To make the injection easiest you can the the Gatejs SPDY/HTTP proxy and use the injection gatejs opcode - it works both on forward and reverse proxy.
Gatejs injection will try to add you html code into a content of type HTML (text/html).
Below a forward proxy example using injection.
var serverConfig = function(bs) { return({
hostname: "testServer0",
runDir: "/tmp/gatejs",
dataDir: "/path/to/dataDir",
logDir: "/var/log/gatejs",
http: {
testInterface: {
type: 'forward',
port: 8080,
pipeline: 'pipetest'
},
},
pipeline: {
pipetest: [
['injection', {
code: "<h1>w00t injection</h1>"
}],
['proxyPass', { mode: 'host', timeout: 10 }]
],
}
})};
mk-
Related
I'm sanitizing CDATA content from various third-party XML feeds, stripping all HTML server-side and using Linkify.js.org (v3.0.3) to safely reapply HTML tags to the sanitized plaintext links client-side.
My project relies a lot on jQuery (v3.6.0).
The linkify jQuery DOM Data API is working great on links and email addresses, but hashtags are proving problematic. By default, hashtags redirect to https://my-domain.com/current-dir/#<HashTag>, but I'd like them to redirect to https://twitter.com/hashtag/<HashTag>. I know this is possible from the demo examples, but I'd like to stick with a jQuery solution, and maintain the div data attributes if possible.
I've read the documentation from Linkify.js.org/docs/ but can't figure out how to change the hashtag URL without dropping the jQuery div data attributes.
Below is a simple example (it's important I maintain a _blank HREF target):
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Linkify</title>
</head>
<body>
<div data-linkify="this" data-linkify-target="_blank">
Domain Test: domain.com. Email Test: email#address.com. HashTag Test: #Linkify.
</div>
<script src="/js/jquery.min.js"></script>
<script src="/js/linkify.min.js"></script>
<script src="/js/linkify-jquery.min.js"></script>
<script src="/js/linkify-plugin-hashtag.min.js"></script>
</body>
</html>
Work's great, but as mentioned, #Linkify redirects to the same page (e.g; https://my-domain.com/current-dir/#Linkify).
Client-side JS is not my strong point, but is there a data-linkify attribute I can use to change the HashTag destination to Twitter? Or additional jQuery code I can use to modify the behaviour of the linkify-plugin-hashtag.min.js plugin?
Use the hashtag plugin options... And since you do not want to call linkify directly, you'll need to play with the default options.
If you add this, it should work out.
linkify.options.defaults.formatHref.hashtag= (href) =>
'https://twitter.com/hashtag/' + href.substr(1);
You can read more at https://linkify.js.org/docs/plugin-hashtag.html and https://linkify.js.org/docs/options.html
I have created a login/signup system which submits values to a php file and connects the database to login. I'm concerned about the security of my login system from the client side, so security in the login.php and script.js. What are the things I need to take into consideration to make a secure login system. As in the security in the XMLHttpRequest or in the input fields of the client side.
login.php
<?php
session_start();
?>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LOGIN</title>
</head>
<body>
<?php
if (isset($_SESSION['user_id'])) {
header ("Location: index.html");
exit();
}
?>
<input id="inserted_id" type="text" placeholder="Account Name/e-mail" />
<p>
<input id="inserted_password" type="password" placeholder="Password" />
<p>
<button id="login_submit" type="submit">Login</button>
<script src="script.js"></script>
</body>
</html>
script.js:
document.getElementById("login_submit").onclick = function () {
var inserted_id = document.getElementById("inserted_id").value;
var inserted_password = document.getElementById("inserted_password").value;
http_request("web_includes/login.inc.php?inserted_id=" + inserted_id + "&inserted_password=" + inserted_password);
}
function http_request(url) {
var xml = new XMLHttpRequest();
xml.open("GET", url);
xml.onload = function () {
if (xml.responseText == "SUCCESS") {
window.open("index.html", "_self", "", false);
} else {
console.log("FAIL");
}
}
xml.send(null);
}
Unsure about XMLHttpRequest's, but research;
CSP: Content Security Policy, Which is specified
in the HTML Meta Tags.
..(to Block or negate Cross-site-Scripting aswell as other threats). ..................................https://www.youtube.com/watch?v=JbfNWg6JS4U
CORS: Cross Origin resource Sharing.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Sha256 & other versions.
Hashing+Salt+pepper are a similar concept. many videos on youtube about ................this....
Also Research. Nonce's (Not the Jail kind).
it stands for a Number which is used once,
Similar to a key. That only your website & Database will have access to or the full number atleast..
(Change XMLHttpRequest to XMLHttpsRequest with the S meaning secure.)
Not viable apparently. or Automatically chosen.
& Could possibly put your whole Login form inside of an Iframe Which you can then specify individual Security attributes on. through the 'Sandboxing' feature.
(Not sure this is necessary if you implement the others or good practice, but it might add an extra layer of frustration to any potential attacker.)
for the PHP side aswell as any Javascript files use RegEx functions to block any attempt to add code; Blocking;
{Z}()[]^></#..etc.....
Just thought of another thing that came to mind. There are websites such as File2hd where you can download websites entire js/css/php/json/ajax etc....
There is a way to block these requests but thats something you'd have to research... it is a very handy site though for analyzing & learning other peoples code...
.php file extension cannot generally be viewed or altered from client side,
unless they are very skilled.. But CSP is your best bet with hash+salt+pepper + RegEx...
A combination of any of the above should make it farely secure... Kind Regards Tao.
Hope this helps :)..
I'm going to create a single page javascript application. It will load different page content based on the url being modified, either by the hash or the html history API depending on the browser.
My though was to use this plugin in order to have the hash fallback for older browsers.
var location = window.history.location || window.location;
handleUrlChange(location.href);
$(document).on('click', 'a.ajax', function(e) {
e.preventDefault();
history.pushState(null, null, this.href);
handleUrlChange(this.href);
});
$(window).on('popstate', function(e) {
handleUrlChange(location.href);
});
function handleUrlChange(url){
// example url: www.foo.com?page=details&id=1
var page = getQueryStringParam('page') || 'index';
$('#dynamic-content').load(page + '.html');
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="header"></div>
<div id="dynamic-content"></div>
<div id="footer"></div>
</body>
</html>
My question is if there are any frameworks that already does this? I don't want to re-invent the wheel here.
There are plenty of solutions, like:
https://millermedeiros.github.io/crossroads.js/
http://stoodder.github.io/finchjs/
http://backbonejs.org/#Router
https://docs.angularjs.org/tutorial/step_07
You can choose what's fits you most. If you don't want to use backbone features like models or collections, or angular framework, and you need just routing, use crossroads.js or finch.js, or just type in google: "Javascript routing" to find other libraries.
Personally, I used only backbone routing.
http://backbonejs.org/#Router
It's easy to use, automatically checks if History API can be used, if not, it uses hash navigation.
I'm writing a static web site that uses JQuery to make some AJAX calls to a RESTful API and populate the page with data.
The site functions correctly (and quickly), everything is good.
As I extend the site and add additional pages, I'm noticing that I'm duplicating certain regions on every page.
For instance, each page shares a common header element.
<header>...Some non-trivial content...</header>
Rather than repeat this definition on each page is there some mechanism, by which, I can define this section once and include it in each document.
Remember that the pages must be served statically but any standard complaint browser functionality can be utilised.
Is there a good way to do this, and what is it or, will I have to abandon DRY principles for this aspect of my client side code?
There's definitely some ways to achieve this. You could either do it using some features of your server-side language that allows to include the content of a page in another page, or if you do not have any server-side technology, you could simply put that code in it's own html document and load it's content using AJAX.
In jQuery it could look like:
$('#header').load('header.html');
However, if the content isin't static for all pages, you could always define a JS module that would be responsible to render this header. You module could make use of a client-side templating engine, like Mustache, Handlebars, etc. However you do not have to use any of these.
Here's a simple example:
DEMO
//in somefile.js, please note that you should namespace your modules
var Header = {
//default config
config: {
el: '#header',
title: 'Some title'
},
init: function (config) {
var cfg = this.config = $.extend({}, this.config, config);
$(cfg.el).html('<h1>' + cfg.title + '</h1>');
}
};
$(function () {
Object.create(Header).init({
title: 'Some other title'
});
Object.create(Header).init({
el: '#header1',
title: 'Yeah'
});
});
As I mentioned in the comment, this is how I do it:
main.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Main page</title>
<sript src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function(){
$('#commonsection').load('reusablefile.htm');
// which is eqvivalent to:
//
// $.ajax({
// url: 'reusablefile.htm',
// dataType: 'html',
// success: function(data){
// $('#commonsection').html(data);
// }
// });
});
</script>
</head>
<body>
<div id="commonsection"></div>
</body>
</html>
reusablefile.html:
<script>
(function($){ //separate scope to keep everything "private" for each module
//do additional javascript if required
})(jQuery);
</script>
<p>...Some non-trivial content...</p>
You could use jQuery's ajax as to load the header file. In each file you could load the html like so:
$('#header').load('header.html');
Since you're already using AJAX calls to populate your site with data, you could do the same for the common regions.
Just store the HTML for those regions in a separate file and load it in the page with AJAX. Also, you can work with caching using the Cache-Control headers on that file so you don't reload the entire content from the server with each page load.
If you're using straight HTML, you could do it with a SSI include command or by creating a template page and including it in jQuery. Both of these links might help you
Include another HTML file in a HTML file
and
http://www.htmlgoodies.com/beyond/webmaster/article.php/3473341/SSI-The-Include-Command.htm
It looks like this in modest:
main.xhtml
<?xml version='1.0' encoding='UTF-8'?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<include>reusablePiece</include>
</head>
<body>
<reusablePiece/>
</body>
</html>
reusablePiece.xml
<header>...Some non-trivial content...</header>
Very simple would be the jQuery .clone() function.
If you have more complex content I recommend looking at Handlebars.js which is a full fledged JS templating engine.
Here's a situation. My customers would be having their own web pages. On that page they might have an iFrame in which they can show a page located on my server. Outside the iFrame they would have simple buttons, which when clicked should execute javascript functions in iFrame.
So basically the code of customer's web page on customer's domain would be something like this
<input type="button" value="Say Hi" id="TestButton">
<iframe src="myserver.com/some_html_page.htm" width="800" height="550"></iframe>
And code of myserver.com/some_html_page.htm would be
$("#TestButton").click(function(){
alert("Hi");
});
I did my reserach and I am aware of the Browser Security issues, but I want to know is there any way to handle this, may be with json or something ?
As you can already tell (given the parent and child are on different domains), you definitely cannot reach up from the child iFrame into the parent to listen for events.
One way around this is to pass messages between the pages. This will require your clients to include additional javascript in their page as well as the iFrame which points to your server. This is supported in native javascript with postMessage, but including the library #Mark Price suggests will make your life much easier.
So here goes an example:
Clients Page:
...
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.postMessage.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#TestButton").click(function(){
jQuery.postMessage("say_hi", "myserver.com/some_html_page.htm");
});
});
</script>
</head>
<input type="button" value="Say Hi" id="TestButton">
<iframe src="myserver.com/some_html_page.htm"></iframe>
Code on myserver.com/some_html_page.htm:
...
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.postMessage.min.js"></script>
<script type="text/javascript">
// you will need to set this dynamically, perhaps by having your
// clients pass it into the URL of the iFrame,
// e.g. <iframe src="myserver.com/some_html_page.htm?source_url=..
var source_origin = "clients_page.com/index.html";
var messageHandler = function (data) {
// process 'data' to decide what action to take...
alert("Hi");
};
$.receiveMessage(messageHandler, source_origin);
</script>
</head>
Probably it would be nice to bundle the client code up into a single library that they could include, so your clients aren't burdened with writing their own javascript.
As a caveat, I wrote this code off the top of my head and it is likely be rife with typos. I have used this library before to accomplish similar goals, and I hope this answer is a useful jumping off point for you (along with the plugin documentation).
Let me know if I can clarify anything, and best of luck! :)
You could try this jquery plugin from Ben Alman, providing you can have the plugin running on both yours, and your clients servers - see the examples for ways to execute js cross domain :
http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html
Lets consider if you have a function called test() which loads under Iframe, then you can access that test() function as below
document.getElementsByName("name of iframe")[0].contentWindow.functionName()
e.g.
document.getElementsByName("iframe1")[0].contentWindow.test()
One of the common patterns of doing cross-domain requests, is using JSONP.