Skip to content

Commit

Permalink
Merge pull request #17 from kimmel/master
Browse files Browse the repository at this point in the history
Added notes on Perl taint mode. Converted from Textile to Markdown. Added a content license.
  • Loading branch information
petdance committed Mar 6, 2012
2 parents 119c9fb + fb2ad31 commit f3e3e40
Show file tree
Hide file tree
Showing 32 changed files with 689 additions and 692 deletions.
12 changes: 6 additions & 6 deletions Makefile
Expand Up @@ -31,14 +31,14 @@ test: crank

messages:
# wrap textile paragraphs into TT loc fragments
for textilefile in $(SOURCE)/*.textile ; do \
perl -lne'BEGIN {$$/ = "\n\n";}; print "[% |loc %]$${_}[% END %]\n"' \
< $$textilefile > $$textilefile.tt2 ; done
# for textilefile in $(SOURCE)/*.textile ; do \
# perl -lne'BEGIN {$$/ = "\n\n";}; print "[% |loc %]$${_}[% END %]\n"' \
# < $$textilefile > $$textilefile.tt2 ; done
# extract string literals to po template
xgettext.pl -g -u -P tt2 -o $(POTEMPLATE) tt/* $(SOURCE)/*
# xgettext.pl -g -u -P tt2 -o $(POTEMPLATE) tt/* $(SOURCE)/*
# update po files
for pofile in $(LOCALE)/*.po ; do \
msgmerge -U $$pofile $(POTEMPLATE) ; done
# for pofile in $(LOCALE)/*.po ; do \
# msgmerge -U $$pofile $(POTEMPLATE) ; done

# This is only useful for Andy
rsync:
Expand Down
10 changes: 7 additions & 3 deletions README.markdown
@@ -1,7 +1,11 @@
This project is the source code for http://bobby-tables.com/, plus the
Perl code that converts it from Markdown format into HTML and uploads
it to the server.

Repository layout
-----------------

s page bodies in Textile format
s page bodies in Markdown format
tt templates in Template::Toolkit format
static images and styles
share/locale translations in gettext format
Expand All @@ -19,7 +23,7 @@ For building:
Locale::Maketext::Lexicon
Locale::Maketext
Template
Text::Textile
Text::Markdown

For testing:

Expand All @@ -31,7 +35,7 @@ Contributing page content
1. Modify templates or page bodies. New pages have to be registered in the file `crank`.
2. Run `make` to build the site and inspect the result in the `build` directory.
3. Run `make test` to check for HTML errors.
4. Commit/publish changes, see `s/index.textile`.
4. Commit/publish changes, see `s/index.md`.

Contributing translations
-------------------------
Expand Down
30 changes: 9 additions & 21 deletions crank
Expand Up @@ -8,7 +8,7 @@ eval 'use Carp::Always'; # Not everyone has it
use Getopt::Long;
use File::Slurp;
use Encode qw(decode_utf8);
use Text::Textile ();
use Text::Markdown ();
use Template ();
use Template::Constants qw( :debug :chomp );

Expand Down Expand Up @@ -49,8 +49,7 @@ my $pages = [

MAIN: {
my $handle = Local::L10n->get_handle; # set LANG to localise
my $textile = Text::Textile::Bobby->new(disable_encode_entities => 1);
$textile->flavor( 'xhtml1' );
my $m = Text::Markdown->new;

my @sidelinks;

Expand Down Expand Up @@ -95,30 +94,19 @@ MAIN: {
while ( @pages ) {
my ($section,$desc) = splice( @pages, 0, 2 );

my $source = read_file( "$sourcepath/$section.textile.tt2" );
my $source = read_file( "$sourcepath/$section.md" );
my $first_pass;
$tt_first_pass->process( \$source, undef, \$first_pass )
|| die sprintf("file: %s\nerror: %s\n", "$sourcepath/$section.textile.tt2", $tt->error);
$vars->{body} = $textile->process( decode_utf8($first_pass) );
$vars->{body} =~ s{<code>\n}{<code>}smxg;
|| die sprintf("file: %s\nerror: %s\n", "$sourcepath/$section.md", $tt->error);

my $html = $m->markdown(decode_utf8($first_pass));
$html =~ s{<code>\n}{<code>}smxg;
$vars->{body} = $html;

$vars->{currlang} = ( $desc eq 'Home' ) ? '' : $desc;
$vars->{rel_static} = ( 'C' eq $ENV{LANG} ) ? q() : q(../); # path prefix to static assets
$vars->{rfc_1766_lang} = ( 'C' eq $ENV{LANG} ) ? 'en' : [map {tr/_/-/;$_} $ENV{LANG}]->[0];
$tt->process( 'page.ttml', $vars, "$section.html", { binmode => ':encoding(UTF-8)' } )
|| die sprintf("file: %s\nerror: %s\n", "$section.html", $tt->error);
}
}

package Text::Textile::Bobby;

use base 'Text::Textile';

# This is for inline code formatting
sub format_code {
my $self = shift;

my $text = $self->SUPER::format_code( @_ );
$text =~ s/<code>/<code class="inline">/g;

return $text;
}
14 changes: 14 additions & 0 deletions s/asp.md
@@ -0,0 +1,14 @@
ASP
===

objCmd.CommandType = adCmdText;
objCmd.CommandText = "UPDATE members SET photo = @filename WHERE memberID = @memberID";
objCmd.Parameters.Append(objCmd.CreateParameter("@memberID", adInteger, adParamInput, 4, memberid ));
objCmd.Parameters.Append(objCmd.CreateParameter("@filename", adVarChar, adParamInput, 510, fileName));
objCmd.Execute(adExecuteNoRecords);
gblDelobjParams(objCmd);

To do
-----

Add some narrative
14 changes: 0 additions & 14 deletions s/asp.textile

This file was deleted.

33 changes: 33 additions & 0 deletions s/coldfusion.md
@@ -0,0 +1,33 @@
ColdFusion
==========

In ColdFusion there is a tag called <code class="inline">cfqueryparam</code> that should be used whenever writing inline queries.

<cfquery name="queryTest">
SELECT FirstName, LastName, Phone
FROM tblUser
WHERE Status =
<cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#form.status#">
</cfquery>


Stored procedures can be invoked with the <code class="inline">cfstoredproc</code> and <code class="inline">cfprocparam</code> tags.

Recent versions of ColdFusion provide a set of functions to run queries that
have a slightly different syntax, but still provide parameterized queries.


<cfscript>
var myQuery = new Query(sql="
SELECT FirstName, LastName, Phone
FROM tblUser
WHERE Status = :status
");
myQuery.addParam(
name = "status",
value = form.status,
cfsqltype = "cf_sql_varchar"
);
var rawQuery = myQuery.execute().getResult();
</cfscript>

33 changes: 0 additions & 33 deletions s/coldfusion.textile

This file was deleted.

22 changes: 22 additions & 0 deletions s/csharp.md
@@ -0,0 +1,22 @@
C\#
===

From the [C# Online](http://en.csharp-online.net/) wiki page [ASP.NET Security Hacks--Avoiding SQL Injection](http://en.csharp-online.net/ASP.NET_Security_Hacks%E2%80%94Avoiding_SQL_Injection)


SqlCommand userInfoQuery = new SqlCommand(
"SELECT id, name, email FROM users WHERE id = @UserName",
someSqlConnection);

SqlParameter userNameParam = userInfoQuery.Parameters.Add("@UserName",
SqlDbType.VarChar, 25 /* max length of field */ );

// userName is some string valued user input variable
userNameParam.Value = userName;

Or simpler:


String username = "joe.bloggs";
SqlCommand sqlQuery = new SqlCommand("SELECT user_id, first_name,last_name FROM users WHERE username = ?username", sqlConnection);
sqlQuery.Parameters.AddWithValue("?username", username);
23 changes: 0 additions & 23 deletions s/csharp.textile

This file was deleted.

10 changes: 10 additions & 0 deletions s/delphi.md
@@ -0,0 +1,10 @@
Delphi
======

To use a prepared statement, do something like this:

query.SQL.Text := 'update people set name=:Name where id=:ID';
query.Prepare;
query.ParamByName( 'Name' ).AsString := name;
query.ParamByName( 'ID' ).AsInteger := id;
query.ExecSQL;
11 changes: 0 additions & 11 deletions s/delphi.textile

This file was deleted.

17 changes: 17 additions & 0 deletions s/dotnet.md
@@ -0,0 +1,17 @@
.NET
====

Reference:

- [SqlCommand.Prepare](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.prepare.aspx) in the .NET Framework Class Library

Articles:

- [SQL injection](http://msdn.microsoft.com/en-us/library/ms161953.aspx) on MSDN
- [SQL Injection and how to avoid it](http://blogs.msdn.com/tom/archive/2008/05/29/sql-injection-and-how-to-avoid-it.aspx) on the ASP.NET Debugging blog

To do
-----

- Add some narrative
- Show code examples
16 changes: 0 additions & 16 deletions s/dotnet.textile

This file was deleted.

86 changes: 86 additions & 0 deletions s/index.md
@@ -0,0 +1,86 @@
Who is Bobby Tables?
====================

<p>
<a href="http://xkcd.com/327/"><img src="img/xkcd.png" alt="xkcd Bobby Tables Cartoon" /></a>
<a href="http://xkcd.com/327/">From the comic strip xkcd</a><br />
<b>School</b>: "Hi, this is your son's school. We're having some computer trouble."<br />
<b>Mom</b>: "Oh, dear -- Did he break something?"<br />
<b>School</b>: "In a way. Did you really name your son Robert'); DROP TABLE Students;-- ?"<br />
<b>Mom</b>: "Oh. Yes. Little Bobby Tables we call him."<br />
<b>School</b>: "Well, we've lost this year's student records. I hope you're happy."<br />
<b>Mom</b>: "And I hope you've learned to sanitize your database inputs."<br />
(title text: "Her daughter is named Help I'm trapped in a driver's license factory.")
</p>

How to avoid Bobby Tables
=========================

There is only one way to avoid Bobby Tables attacks

- Do not create SQL statements that include outside data.
- Use parameterized SQL calls.

That's it. Don't try to escape invalid characters. Don't try to do it yourself. Learn how to use parameterized statements. Always, every single time.

The strip gets one thing crucially wrong. The answer is not to "sanitize your database inputs" yourself. It is prone to error.

Examples
========

See the sidebar to the left for your specific language.

Other random resources
======================

- [SQL Injection Myths and Fallacies](http://www.slideshare.net/billkarwin/sql-injection-myths-and-fallacies)
- [http://www.schneier.com/blog/archives/2008/10/how_to_write_in.html](http://www.schneier.com/blog/archives/2008/10/how_to_write_in.html)
- [http://st-curriculum.oracle.com/tutorial/SQLInjection/](http://st-curriculum.oracle.com/tutorial/SQLInjection/)

Patches welcome
===============

Don't see a language that you'd like to see represented? Please let me know if you have updates or additions through one of these methods, in decreasing order of preference.

- Fork the [bobby-tables repository at github](http://github.com/petdance/bobby-tables), make your changes, and send me a pull request.
- Add an issue in the [issue tracker](http://github.com/petdance/bobby-tables/issues).
- Email me, Andy Lester, at andy at petdance.com.

Translations also welcome
=========================

Help translate this site! There are only 100 phrases. No programming necessary.

See the instructions at the [bobby-tables repository at github](http://github.com/petdance/bobby-tables#readme).

To do
=====

- Explain why creating code from outside data is bad.
- Potential speed win when reusing prepared statements.

Thanks
======

Thanks to the following folks for their contributions:

- Kirk Kimmel
- Nathan Mahdavi
- [Hannes Hofmann](http://www5.informatik.uni-erlangen.de/en/our-team/hofmann-hannes)
- [Mike Angstadt](http://www.mangst.com)
- [Peter Ward](http://identi.ca/flowblok/)
- [David Wheeler](http://justatheory.com)
- Scott Rose
- Erik Osheim
- Russ Sivak
- [Iain Collins](http://iaincollins.com)
- Kristoffer Sall Hansen
- Jeff Emminger
- [Travis Swicegood](http://www.travisswicegood.com/)
- [Will Coleda](http://www.coleda.com/users/coke/)
- Kai Baesler
- Mike Markley
- [Michael Schwern](http://schwern.dreamhosters.com/)
- [Jeana Clark](http://jeanaclark.org/)
- [Lars Dɪᴇᴄᴋᴏᴡ](http://search.cpan.org/~daxim/)
- [Jani Hur](http://www.jani-hur.net)

0 comments on commit f3e3e40

Please sign in to comment.