Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

XSS Protection in cgi application

by newperldeveloper (Sexton)
on Nov 03, 2021 at 11:59 UTC ( [id://11138370]=perlquestion: print w/replies, xml ) Need Help??

newperldeveloper has asked for the wisdom of the Perl Monks concerning the following question:

I have to maintain an old cgi application that for whatever reason the boss doesn't want to upgrade to a modern frame work. The dilemma is we got hit my a security scan and we are susceptible to xss attacks. How do I protect against that in cgi. What I have done so far to curb the bleeding is I've added a regex to top of script that looks for words in url script, onload,cookie,mouse,document and a few others that I will never use in the url. But that is just a stop gap. Is there anything I can further do to protect against this attack. https://www.mysite.com?store="><script>alert('Gotcha!')</script>&aisle=">AA&prod=456&color=">8 The url is encoded %22%3E%3Cscript%3Ealert but that doesn't work. Any help would be appreciated.

Replies are listed 'Best First'.
Re: XSS Protection in cgi application
by stevieb (Canon) on Nov 03, 2021 at 15:11 UTC
    for whatever reason the boss doesn't want to upgrade to a modern frame work

    Come on, let's be honest here. The reason is money. Someone who isn't interested in investing in new, stable technology when the old technology is recommended against, won't be interested in investing much in good security practices either.

    That mentality changes quickly when the company is hacked or taken for ransom. At that point though, everyone is scrambling to patch things in an uncontrolled manner, and far more money is spent recklessly than if the original investment in better practices had been made. I have seen this time and time again in my 20+ years in the industry.

    PS. From the CGI documentation itself:

    "CGI.pm is no longer considered good practice for developing web applications, including quick prototyping and small web scripts. There are far better, cleaner, quicker, easier, safer, more scalable, more extensible, more modern alternatives available at this point in time."

      I started to comment along similar lines. He's expecting you to make his Model T able to fuel up at a Tesla supercharging station and (of course) needs it by last week . . .

      You should point out to your boss that in order to give an ancient CGI script the protections of a decade-or-so worth of development of security improvements that have gone into more modern frameworks he should expect to need a decade-or-so of work backporting them. There'll probably be some low hanging fruit you can integrate as was mentioned upthread but you'll have to do the work to wire it in yourself (which also means you get fewer eyeballs on it; possibly enough to placate the scanning ones, at least, maybe).

      Of course even if you rewrite using something modern those improvements are just a more solid foundation upon which you can build and you still need to pay attention to best practices while you rebuild. They just make it harder, not impossible, to get your foot under the barrel.

      Edit: The reply below will probably get reaped shortly but you can simulate the experince quite easily.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: XSS Protection in cgi application
by NERDVANA (Deacon) on Nov 03, 2021 at 14:41 UTC
    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.

Re: XSS Protection in cgi application
by haj (Vicar) on Nov 03, 2021 at 15:34 UTC
    Some general rules:
    • Don't try to identify malicious content. Identify valid content for your fields, and discard everything else. A field named "store" is unlikely to require any of the critical characters <>&.
    • If you include form fields in a response, you need to HTML-escape them as you would for your own texts. HTML-encoding "&lt" is different from URL-encoding "%3C". If you build href or other URL attributes, you need to apply both encodings on top of each other.
    • Be aware that attackers don't use a browser to construct their URLs. Validating form fields with HTML data types or JavaScript is nice for convenience, but doesn't help for your application's security.
Re: XSS Protection in cgi application
by perlfan (Vicar) on Nov 03, 2021 at 19:41 UTC
    > old cgi application that for whatever reason the boss doesn't want to upgrade to a modern frame work

    I mean at some point, those frameworks with be out of favor. CGI is for ever. xD..But you might be able to also take a look at CGI::Tiny. I have not used it yet, but seems like a good way to do an older thing (or clean up an old thing).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11138370]
Approved by marto
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-19 23:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found