HTML5 Hyperlink Auditing (ping attribute)

This was a browser feature that was relatively unknown until recently when several browsers announced that they would be removing support.  It is useful to track instances when a user clicks on a link, as it could be recorded by the server for analysis of user activity.   As it was done out-of-bounds, there was no additional code, such as javascript, required on the client-side for this to occur.

<a href="..." ping="https://example.com/pingreporter">Example link</a>

References:

XFN (XHTML Friends Network)

A big part of Web 2.0 (over the last decade) has been a move toward the semantic internet, whereas each page is representative of data and it’s relationship… we are, in essence, “training” the internet itself.

XFN markup allows you to identify your relationships to other individuals on the links of your website or blog.

HTML4:
<head profile="http://gmpg.org/xfn/11">

HTML5: (removes the ‘profile’ attribute on <head> as such the updated convention is:
<link rel="profile" href="http://gmpg.org/xfn/11" />

Use in content:
<a href="http://www.skotfred.com/" rel="me">My other site</a>

REFERENCES:

REF:

http://reference.sitepoint.com/html/xfn

Href Links as HTTP POST (complex DOM solution)

The earlier post, while easy to implement, has some well known security issues. Now lets get around them. First we’ll remove the FORM from the HTML itself, and instead build it dynamically and insert it into the BODY via the DOM and then submit it with JavaScript.

Again, if you’ve already implemented my prior solutions, this is just a small code refactor.

<html>
<head>
<title>Example FORM Post - DOM</title>
<script type="text/javascript">
/*
* Uses "location.replace()" vs. "location.href()" for all valid links.
* 'replace' has side-effect of 'restricting' back-button, or 'location'
* @param obj Object clicked
* @param x URL
*/
function xlinkObj(obj,url){
//Consider replacing w/ "return xlinkFrm(obj,url); " if you want POST behavior.
window.location.replace(uniqueUrl(url));
return false;
}
/*
* uses a FORM for the requested URL, could be POSTed!
* This is a simple solution, more complex solution COULD build the FORM and then parse attributes into INPUT's
* NOTE: you probably SHOULD NOT use this for external links, unless you intend for them to receive your params!
* @param obj Object clicked (NOT USED in this Example)
* @param x URL
*/
function xlinkFrm(obj,x){
var url=uniqueUrl(x);
var frmObj=xlinkFrmHelp(url);
if(frmObj!=null){
frmObj.submit();
}else{
alert('ERROR!');
}
return false;
}
/*
* Expects URL with queryString as param href
* @param x URL
* @return obj Object of the generated FORM
*/
function xlinkFrmHelp(x){
var rc=null;
try{
var ar = x.split("?");
var act = ar[0];
var str = ar[1];
var id="frm" + xmillis();
var oFORM=document.createElement("form");
oFORM.setAttribute("id",id);
oFORM.setAttribute("method","post");
oFORM.setAttribute("action",act);
if(str!=null){
var parms=str.split('&');
for(i=0; i < parms.length; i++){
var parm=parms[i];
var pair=parm.split('=');
var oINPUT=document.createElement("input");
oINPUT.setAttribute("type","hidden");
oINPUT.setAttribute("name",pair[0]);
oINPUT.setAttribute("value",pair[1]);
oFORM.appendChild(oINPUT);
}
}
var oBODY=document.getElementsByTagName("body")[0];
oBODY.appendChild(oFORM);
rc=oFORM;
}catch(e){
alert("Error"+e);
}
return rc;
}
/*
* generates a timestamp as a number
*/
function xmillis(){
return new Date().getTime();
}
/*
* adds timestamp to URLs to make them unique
* @param URL String
*/
function uniqueUrl(x){
return urlAppender(x,'time',xmillis());
}
/*
* helps to add parms to the url
* @param URL String
* @param aname String
* @param avalue String
*/
function urlAppender(x,aname,avalue){
var delim = "?";
if(x.indexOf("?") >=0) { delim = "&"; }
return x + delim + aname + '=' + avalue;
}
/*
* Abstracts "document.getElementById()" with appropriate error handling.
* @param id String
* @returns Object (NULL when not found!)
*/
function xgetHelper(id){
var obj = null;
try {
obj = document.getElementById(id);
} catch(z) {
var dummy=alert("Error:" + z);
}
return obj;
}
</script>
<a href="javascript:void(0);" onclick="return xlinkObj(this,'index.php');">REFRESH</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'index.php');">TEST-POST</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'index.php?a=b');">TEST-POST2</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'http://www.skotfred.com/hello');">TEST-XSS</a>
</body>
</html>

Cheers!

Href Links as HTTP POST (simple solution)

Another interesting challenge, The standard <a href=”…”></a> style link performs an HTTP GET, however you might want to perform a POST in some cases. HTML does not natively support this behavior, but it can be accomplished in JavaScript. If you have already implemented some of my security ‘hacks’ from previous posts this is only a small change. As usual I’ve included the minimum code required for this task in the example, but you should be able to easily merge the different features back into this!

Later on (in a different post), I’ll expand this to make it even more secure as this solution simply puts all of the URL into the FORM ‘action’ attribute and it would be better to pass them in the FORM body itself to hide them from the URL shown in the browser.

<html>
<head>
<title>Link to FORM POST simple example</title>
<script type="text/javascript">
/*
* Uses "location.replace()" vs. "location.href()" for all valid links.
* 'replace' has side-effect of 'restricting' back-button, or 'location'
* @param obj Object clicked (NOT used in this example)
* @param x URL
*/
function xlinkObj(obj,url){
//Consider replacing w/ "return xlinkFrm(obj,url); " if you want POST behavior in all cases!
window.location.replace(uniqueUrl(url));
return false;
}
/*
* uses a FORM for the requested URL, could be POST'ed!
* This is a simple solution, using an existing empty FORM on the page.
* A more complex and secure solution COULD build the FORM dynamically and then parse attributes into INPUT's
* NOTE: you probably SHOULD NOT use this for external links, unless you intend for them to receive your params!
* @param obj Object clicked (NOT used in this example)
* @param x URL
*/
function xlinkFrm(obj,x){
var frmObj=xgetHelper('frmXlink');
if(frmObj!=null){
frmObj.action=uniqueUrl(x);
frmObj.submit();
}else{
alert('ERROR!');
}
return false;
}
/*
* generates a timestamp as a number
*/
function xmillis(){
return new Date().getTime();
}
/*
* adds timestamp to URLs to make them unique
* @param URL String
*/
function uniqueUrl(x){
return urlAppender(x,'time',xmillis());
}
/*
* helps to add parms to the url
* @param URL String
* @param aname String
* @param avalue String

*/
function urlAppender(x,aname,avalue){
var delim = "?";
if(x.indexOf("?") >=0) { delim = "&"; }
return x + delim + aname + '=' + avalue;
}
/*
* Abstracts "document.getElementById()" with appropriate error handling.
* @param id String
* @returns Object (NULL when not found!)
*/
function xgetHelper(id){
var obj = null;
try {
obj = document.getElementById(id);
} catch(z) {
var dummy=alert("Error:" + z);
}
return obj;
}
</script>
</head>
<body>
<form id="frmXlink" action="#" method="post"></form>
<a href="javascript:void(0);" onclick="return xlinkObj(this,'index.html');">REFRESH</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'index.html');">TEST-POST</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'index.html?a=b');">TEST-POST PARMS</a>
<a href="javascript:void(0);" onclick="return xlinkFrm(this,'http://www.giantgeek.com/hello');">TEST-XSS</a>
</body>
</html>

This just uses an “empty” FORM in the page and uses the new ‘xlinkFrm()’ method to copy the URL to the FORM ‘action’.

Like i said, this is a simple solution as the params are still on the URL making them less secure. I’ll be refactoring it to parse the params to dynamically build the FORM (that will no longer be hardcoded).

Cheers!

<a href=”…” rel=”nofollow”>…</a>

In an effort to reduce what is commonly referred to as “Comment SPAM”, you should consider adding the rel=”nofollow” attribute to any ‘user provided’ link in your website (or Blog). Doing so will prevent many search engines (spiders) from giving the linked site additional ‘value’ or ‘relevance’ because of a multitude of links from around the web. It doesn’t remove ‘value’ from them, just makes your site not give them any additional weight.

To my knowledge; Google, Yahoo!, and MSN all support this markup.

Simply put… the intended effect of this is that any link containing rel=”nofollow” will allow both users and search engines to reach the site, but the existence of the link will not increase the ranking of the site in participating search engines.

Related info: