2

So James Patterson keeps trying to hack my website! Okay, not really, but he has written quite a few books that have titles starting with "Kill" which triggers a HTTP 501/HTTP 505 from our server side firewall.

Here's the situation, our Library Software generates a weekly email report all of the new books added to the collection in the last week. I've made a form (using php/html) where we can C&P this data in and it will transform it into a nice little page showing off our new titles. Once the form is submitted I sanitize the data before it's added to a MySQL database. The "Kill" trigger happens before the data from the form can be passed and processed. The data comes in the format:

Kill shot : an American assassin thriller / Vince Flynn|Flynn, Vince|2012|9781416595205 (hbk.)|NEWBKSHELF|20120207| 

I think the way to do this would be a little bit of javascript that changed every instance of kill to something innocuous and then change it back when I am inserting it into the MySQL db.

However there can be hundreds of entries like the one above, and I'm not very good with javascript, and I'm not sure the how to accomplish the first half of this (eg changing every instance of kill to kxll and Kill to Kxll.) I am fairly confident that when I save the data I can safely change kxll back.

aslum
  • 11,774
  • 16
  • 49
  • 70

4 Answers4

3

Since you don't know if kill is the only special word which is not allowed (maybe man, cat, ls are also forbidden?), you could encode the entire string. For instance, you could convert it to charcodes using this method http://bateru.com/news/2009/10/javascript-tips-convert-string-to-unicode-values/ Then, convert it back on the server side.

naivists
  • 32,681
  • 5
  • 61
  • 85
1

You should hook into the onSubmit() of the form, then check every field, and then replace the value of the submitted field when it contains kill. Best this is done with JQuery, for example

$(function() {
    $("#formid").bind("submit", function(event) {
        $('input')
        .filter(function(){return $(this).val().indexOf("kill") !== false;})
        .each( function(index,element) {
            $(this).val($(this).val().replace(/kill/i, "kxll"));
        });
    });
});

Demo here: http://jsfiddle.net/49psu/4/

You might want to use $('input[value*="kill"]') and .replace(/kill/ig, "kxll") if you want to catch 'kill' anywhere in the inputs.

For more info:

http://api.jquery.com/each/

http://api.jquery.com/bind/

http://api.jquery.com/submit/

http://w3schools.com/jsref/jsref_replace.asp (javascript replace)

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
  • Needs to be case insensitive. Not sure if the jQuery content selector is case sensitive, but replace is. Should use .replace(/kill/ig, "kxll") – kitti Feb 08 '12 at 18:41
  • i like your solution, but the prob reside if he got many words. you don't store your changes and it can become messy. works fine if only kill tho. – Charles Forest Feb 08 '12 at 18:42
  • @WillemMulder Still need to add the 'g' flag, otherwise it will only match the first occurrence. – kitti Feb 08 '12 at 19:09
  • True, but I only assumed one kill at the front of the string (hence, the jquery selector). I'll add it for completness sake :) Thanks! – Willem Mulder Feb 08 '12 at 20:46
  • This seems like it would be the best answer, and I'd mark it as such except I can't get it to work. I'm probably missing something obvious here, but it's not even catching one instance as far as I can tell. – aslum Feb 08 '12 at 20:56
  • Maybe you should return false to cancel the current submit, and then resubmit the form with the changed values? – Willem Mulder Feb 09 '12 at 08:27
  • Created a JSFiddle to test it out, and updated my answer above. Seems like the attribute-selector does not work on user-entered input in 'value'. So I used a filter() function. – Willem Mulder Feb 09 '12 at 08:45
  • Hurrah, got it working... though still needs a tweak or two... 1) I'd like to maintain case (Kill becomes Kxll, kill becomes kxll), and 2) I only want whole words (EG Skilled Assassin doesn't need to be changed, Kill the Assassin does). – aslum Feb 14 '12 at 19:03
  • This might be out of scope considering the original question, but if you post it in a new question and post the link here, I'll answer there! – Willem Mulder Feb 14 '12 at 22:00
1

had a similar problem and my fix is... unorthodox but it did worked.

yourField.replace(/kill/ig, '(ILLEGALTAG#1)');

if you want it to display correctly before he submit form, just put the function on a onsubmit

and you make a sql that contain your illegal tags.

so DB

ID    |   Word
1     |   Kill

when you want to export your data just replace the occurence live.

please note: this solution IS NOT IDEAL, it's just a fix if you rlly can't use alternative (like fix firewall)

Charles Forest
  • 1,035
  • 1
  • 12
  • 30
  • The problem needs to be fixed in the browser with JS, because the data never gets to the PHP server. – kitti Feb 08 '12 at 18:42
0

On submit, you could build a JSON object from the form, then BASE64 encode it and submit it through AJAX while cancelling the original form submit. Base64 decode on the server is natively supported in PHP through

base64_decode($string);

See http://php.net/manual/en/function.base64-decode.php

Base64 on the client-side works through

btoa(string)

See https://developer.mozilla.org/En/DOM/Window.btoa for more info. Only works in Chrome and Firefox natively, otherwise use the script as mentioned here

How can you encode a string to Base64 in JavaScript?

Community
  • 1
  • 1
Willem Mulder
  • 12,974
  • 3
  • 37
  • 62