Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: XSS Protection in cgi application

by NERDVANA (Deacon)
on Nov 03, 2021 at 14:41 UTC ( [id://11138381]=note: print w/replies, xml ) Need Help??


in reply to XSS Protection in cgi application

This topic is worthy of a book.... but for starters, you must treat every parameter to your script like a radioactive fuel rod that is going to destroy your app. Assume every parameter is dangerous until you have compared it to a regex for validity or sanitized it in some way. And if it is user text meant to be rendered later, where you pretty much have to accept whatever they gave you, then make absolutely sure you escape the text before combining it into a different language like HTML or SQL.

The most common mistake in old CGI code is to combine user input with HTML and write it on STDOUT. This lets people run arbitrary javascript on the page of anyone who follows their link. Especially bad if an evil person gets the administrator to click their link. The best perl solution to this problem is to use a templating engine that encodes html entities by default, and forces you to declare it when you know that a string contains safe html. A popular example is Text::Xslate. The SYNOPSIS contains a good example of how to use it. A second option is to strip out HTML tags using something like HTML::Defang. Don't forget to also escape your exceptions if you catch Perl exceptions and show them to the user. (the Perl de-facto standard for escaping html entities is HTML::Entities.) But better, don't show them to the user; write them to a log file or database table and tell the user to contact you with a unique ID or timestamp that you can use to look up the error.

The second most common mistake in CGI is to combine user input with strings of SQL and feed that to your database. This allows an attacker to execute whatever SQL they like on your database. See any of 10,000 articles on the topic of "sql injection". The solution to the second problem is to always use placeholders for the parameters in your SQL. DBI lets you do this with question marks like $dbh->do("update tablename set columnname = ? where id = ?", {}, $newvalue, $id) This way DBI performs the escaping for you.

The third most common mistake is to construct a filename out of user-provided input. Always constrain the characters used in file names to restrict obvious problems like ".." and "/" and use unix permissions to ensure that the apache user can only write to directories that you expect it to write to. Also ensure that other untrusted users on the system don't have permission to create symlinks there. In fact you should test any filename that the user had any control over to ensure that the path being written is not a symlink. I'm not aware of specific tools for solving this problem other than regexes, but in general just don't do it. Instead, store the filename in the database, and write the file using the record ID as the name.

Hope that helps. But in general, if an app was written without attention to security, it probably needs rewritten.

Replies are listed 'Best First'.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11138381]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-03-28 10:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found