LAN Web TCP Delphi

Title: Cross-Site Scripting Protection (aka Encoding and Filtering HTML)
Question: In this article Ill present a unit that can both Encode data for display in an HTML document, and also ensure that invalid characters (filtering) that can be used for cross-site scripting are prevented from entering.
Answer:
Cross-Site Scripting Protection (aka Encoding and Filtering HTML)
In this article Ill present a unit that can both Encode data for display in an HTML document, and also ensure that invalid characters (filtering) that can be used for cross-site scripting are prevented from entering.
For more information about cross-site scripting and malicious code problems, please visit:
http://www.cert.org/tech_tips/malicious_code_mitigation.html/
Overview
To summarize the article, any HTML data that is presented to the user from disparate data sources (which may not always be in your control) should be filtered of characters that can affect the display of HTML or allow embedded script viruses.
Filtering Data
For example, lets say that you have a form on your web site that allows a user to enter a contest, on this form they enter their email address and first name and then hit submit which adds a record to your database. Of course, several validity checks, such as size of contest, etc. will take place, but in most cases the data is not checked for malicious HTML code. Continuing this example, lets say you have another program that will send out an HTML e-mail, which contains the first name and e-mail address (basically a mail merge).
I as a malicious user can enter the contest submitting my targets e-mail address, and a small virus (not necessarily harmful) in the first name field; when the e-mail is sent out through the second program the recipient can be passed code to be executed in their web-browser against their will (and with the recent sting of Internet Explorer and Microsoft Office bugs, this could be a major issue).
This scenario can be fixed by simply filtering out the few characters that should not be allowed if the data is to be ultimately displayed in a web-browser.
The function, in the abHTMLFilters unit, FilterData will delete any characters that should not be allowed in the data (based on CERTs recommendation).
Encoding Data
The flip side of filtering is encoding. Encoding allows you to safely display any code, which would normally be interpreted by the web-browser as formatting instructions or script, as text. As a simple example, this can be used to display the source of an HTML file in a browser.
The function, in the abHTMLFilters unit, EncodeData will encode any characters that should not be allowed in the data (based on CERTs recommendation) with its HTML equivalent so it can be displayed.
I hope you found this article and function to be useful; Id love to hear your comments, suggestions, etc.
The following is the source code for the functions described above, feel free to use the code in your own programs, but please leave my name and address intact!
// ---------------------------ooo------------------------------ \\
// 2000 David Lederman
// dlederman@internettoolscorp.com
// ---------------------------ooo------------------------------ \\
unit abHTMLFilters;
interface
function FilterData(Data : String) : String;
function EncodeData(Data : String) : String;
implementation
const
IsBadChar : array[0..255] of Boolean = (
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,true,true,false,false,true,true,true,true,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,true,true,false,true,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,false,
false,false,false);
const
ReplaceBadChars : array[0..255] of String = (
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','"','#','','','&',''','(',')','','',
'','','','','','','','','','','',
'','','','',';','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','','','','','','','','','',
'','','');
// ---------------------------ooo------------------------------ \\
// This function will filter out all dangerous data for web
// display.
// ---------------------------ooo------------------------------ \\
function FilterData(Data : String) : String;
var
i, DataLen, ActualLen : Integer;
begin
Result := '';
// Get the data length
DataLen := Length(Data);
// Check if we can escape early
if DataLen = 0 then Exit;
for i := 1 to DataLen do // Iterate
begin
if not IsBadChar[Ord(Data[i])] then Result := Result + Data[i];
end; // for
end;
// ---------------------------ooo------------------------------ \\
// This function will encode (for display) all dangerous data
// for weg display.
// ---------------------------ooo------------------------------ \\
function EncodeData(Data : String) : String;
var
i, DataLen, ActualLen : Integer;
begin
Result := '';
// Get the data length
DataLen := Length(Data);
// Check if we can escape early
if DataLen = 0 then Exit;
for i := 1 to DataLen do // Iterate
begin
if not IsBadChar[Ord(Data[i])] then
begin
Result := Result + Data[i];
end
else
begin
Result := Result + ReplaceBadChars[Ord(Data[i])];
end;
end; // for
end;
end.