back to article SQL attacks inject government sites in US, UK

A new round of SQL injection attacks has infected millions of web pages belonging to businesses and government agencies, including those that belong to the National Institutes of Health and Education Department in the US and the UK Trade & Investment. This search shows at least 1.45 million infected pages and queries here and …

COMMENTS

This topic is closed for new posts.
  1. Anonymous Coward
    Unhappy

    the .us domain doesn't look so hot either

    That's one of the big ones used by the US K-12 public school system and local municipalities...

    http://www.google.com/search?hl=en&q=site%3A.us+%22script+src%3Dhttp%3A%2F%2F*%2F%22%22ngg.js%22|%22js.js%22|%22b.js%22&btnG=Search

  2. Cliff
    Thumb Down

    AVG says they're all safe...

    You know AVG's annoying new feature to put a safe green tick beside every result in google? Even pages google says 'this may harm your computer' are marked safe by AVG. Damn I hate that tick and popover windows.

  3. Anonymous Coward
    Anonymous Coward

    I guess

    I guess what this means is we should treat every site with the suspicion normally given to p0rn sites... better still just use the internet for p0rn!

  4. Alan W. Rateliff, II
    Paris Hilton

    @Cliff

    AVG's SafeSearch only scans the first page of the search result, and IIRC does not touch the JavaScript. Once you visit the site, AVG slams the hammer down.

    And, for the record, McAfee SiteAdvisor also gives a large number of these pages the pass.

    BTW, I am not at all impressed with the quote of 1.45million sites being infected using this query. The Google results are (currently) around 1.48million, but a lot of them are from forums describing the injection attack. I'm not saying that this significantly affects the number of real infections, but it is at least noteworthy. As well, I am finding that quite a few in the first few pages of results have already fixed the problem.

    Paris, noteworthy for slamming the hammer down, and giving the pass.

  5. Geoff Mackenzie

    @Alan W. Rateliff, II

    Clearly, AVG ought to spider entire sites automatically just before you visit them. That would be popular.

  6. Andrew Thomas

    Stop blaming the victims!

    Your article said; "SQL injections take advantage of web developers who write applications that accept user-supplied data without inspecting it for malicious characters. "

    Well, as a one-time victim of these sorts of attacks I can say you really shouldn't blame the website designers. I had a LOT of input validation in my code to catch SQL injection attacks, but these were so subtle and sophisticated they still got through. Instead of using invalid ASCII characters, they encoded the characters in hex and used SQL to decode them into the malicious attack - so my validation script did not pick up the characters:

    http://www.arejae.com/blog/sql-injection-attack-using-t-sql-and-hexadecimal.html

    Website designers are doing their best to prevent these sort of attacks, so stop blaming us - we are fighting against organised gangs in China (apparently) who are devoting masses of manpower to creating extremely sophisticated attacks. STOP BLAMING THE VICTIMS!!

  7. Steve Foster

    @Andrew Thomas

    The linked page shows an attack that relies on the use of unprepared statements - ie the web page is allowed to submit data that is passed directly to SQL to execute. That *is* lame design.

    Values submitted from the web should _only_ be used as parameter values to prepared SQL statements, and those statements should *never* be written in such a way that a parameter might be passed to an EXEC command.

    The example is using ASP, and even that has rudimentary typecast checking, which would prevent the sample attack "data" from being supplied to ADO as anything other than a varchar parameter. Tightly defined parameter types help to protect against values that evade your parameter validation (eg the hex conversion doesn't help a bad guy insert strings of text into a datetime parameter).

  8. Lee Palmer

    As a victim, we are to blame! Just in case somebody reads this and does not know what to do!

    Strip out the semicolons, single quotes and greaterthan and lessthan characters from all input passed to all SQL queries. I missed one input and got clobbered.

    As mentioned on El Reg, before and often.

    Cheers

    Lee

  9. Jonathan Richards

    UK sites compromised

    Amending the google searches offered in TFA:

    ~3860 @ .co.uk

    ~2720 @ .gov.uk

    ~8 @ .ac.uk

    0 @ .mod.uk

    Draw your own conclusions. I'd just like to say that from the web surfer's point of view, this is a very clear reason to have Firefox and the NoScript extension.

  10. Dominic

    @Andrew Thomas

    As Steve has already said, bind your frikkin variables and no SQL Injection problem. This is exactly why java script monkeys shouldn't be allowed with 100 yards of a proper application. It doesn't need sophisticated coding structures, just someone who knows what they are doing

  11. Lee Palmer

    More on semicolon stripping

    @Steve Foster & Dominic

    Yes early binding of variables ensure numerics and date type cannot be messed with, but it does not deal with plain old text/strings. I not sure parameterisation helps ala some MS help texts.

    The semicolon allows SQl requests to run one after the other. e.g.

    SELECT * FROM anytable; SELECT * FROM anytable2; SELECT * FROM anytable3;

    Is legitimate SQL.

    Combine it with singlequotes, the SQL string delimiter, and commenting --

    You can insert your chosen damaging SQL instruction into any existing statement parameterised or not, if the input text box allows you enough characters!

    The singlequote and semicolon close off the prebuilt/programmed first query. Allowing your query to run. The comment chucks away any remaining bit of

    prebuilt/programmed first query.

    Lee

  12. Harry Stottle

    Add Sandboxie to your protection suite

    www.sandboxie.com

    been using it for about a month now on a dozen or so web active machines. Seems pretty faultfree, stable and let's me sleep better at nights knowing that it no longer matters what "infects" my users' machines because it all disappears when they close their browsers. 'course, I can't do anything to stop them handing over sensitive data to phishing sites but that's a horse of a different feather...

  13. Dominic

    @Lee

    When you bind the variable, the query is parsed as eg (select x,y.z from t where v = :1) it then passes the string into the bind variable and runs the parsed query. No way this can be open to sql injection as the query is parsed before any dodgy strings are processed

  14. Lee Palmer

    @Dominic Hi

    Even from your description the input string seems to get directly into the SQL without checks. It may be my lack of understanding, but the query gets parsed then the bind variable/string is added directly. If the completed query is/was parsed then maybe its ok. It depends what parsed means. If parsing means; check the SQL syntax grammer is correct (normal), then trouble. If it means lexically strip for known bad characters (Not the normal meaning) then ok. Also, I would suggest this is better done before adding it into the query, because the query might legitmately have a semicolon in it.

    Cheers

    Lee

  15. Dominic

    @Lee

    set serveroutput on size 1000000

    drop table sql_injection_test

    /

    create table sql_injection_test

    (username varchar2(10),

    password varchar2(10))

    /

    insert into sql_injection_test

    (username,

    password)

    values('user',

    'test')

    /

    create or replace procedure sql_inj_test(in_user VARCHAR2,

    in_pwd VARCHAR2) as

    v_string varchar2(2000);

    found_user varchar2(1);

    begin

    dbms_output.put_line('first run with bind variables');

    v_string := 'select DECODE(count(*),0,'||''''||'N'||''''||','||

    ''''||'Y'||''''||')'||

    ' from sql_injection_test '||

    ' where username = :1 and password = :2';

    execute immediate v_string into found_user using in_user, in_pwd;

    if found_user = 'Y'

    then

    dbms_output.put_line('found user, ok to connect');

    else

    dbms_output.put_line('invalid user. Exit');

    end if;

    dbms_output.put_line('now run without bind variables');

    v_string := 'select DECODE(count(*),0,'||''''||'N'||''''||','||

    ''''||'Y'||''''||')'||

    ' from sql_injection_test '||

    ' where username = '||''''||in_user||''''||

    ' and password = '||''''||in_pwd||'''';

    dbms_output.put_line(v_string);

    execute immediate v_string into found_user;

    if found_user = 'Y'

    then

    dbms_output.put_line('found user, ok to connect');

    else

    dbms_output.put_line('invalid user. Exit');

    end if;

    end;

    /

    prompt *** sql_inj_test('user','test') ***

    begin

    sql_inj_test('user','test');

    end;

    /

    prompt sql_inj_test('user','dunno'||''''||' or '||''''||'a'||''''||' = '||''''||'a');

    begin

    sql_inj_test('user','dunno'||''''||' or '||''''||'a'||''''||' = '||''''||'a');

    end;

    /

  16. Anonymous Coward
    Stop

    @Dominic, @Lee

    I find it appalling that our governement has so many sites that suffer this problem, in fact appalling isn't strong enough it is outright disgraceful. It;s equally fisgraceful that there are those here who are commenting to the effect that avoiding SQL Injection isn't easy, when in fact it is pretty trivial.

    It seems to me to be amazingly easy to design and produce web applications, even using oldish technology like MS ASP with ADO (and SQL Server 2000) that are free from any possibility of succumbing to web injection attacks.and actually to require a extreme lack of awareness of simple principles of design.

    I find it incomprehensible that anyone who cares about modularity of application structure can allow a JavaScript function to contain some SQL – all the JS should do is call stored procedures. It is equally incomprehensible that the JS should have the sort of privileged connection to the DB that allows it to define or redefine any stored procedures (as shown in one example posted above) or indeed have permission to modify the schema in any way. If the website is on an intranet which is believed to be secure it is maybe acceptable for the connection used by the JS to have the privilege required to read or write some data other than through stored procedures, but this is totally unnecessary (and probably undesirable) since in any design shop with serious software engineers as opposed to script kiddies there will be design and programming standards (promoting security and modularity) that preclude use of that privilege in the JS.

    Here's one way to do it - not high tech, not complicated, just simple common sense. To access the database the JS can create an adodb connection object give it a connection string that confers the right level of privilege, and open it; then create an adodb command object and set its commandtype to adCmdStoredProc and its command text to the name of the stored procedure it wants to call (this name must be built in to the JS at some level, not pulled in from a form – why would anyone want the end-user to specify a stored procedure name?), create parameters by invoking the CreateParameter method of the command object using as the parameter values either data generated internally in the JS or data pulled from the form or query string and preprocessed in the JS to be strings, integers, or whatever is required for each parameter (in fact all parameters using data from the form or query string may as well be declared as advarchar and passed as strings) and append them to the command object, and finally create an adodb recordset object, set its properties to adOpenStatic and adUseClient, and assign it the value returned by the execute method of the command object. Any results required can be pulled from the record set (and dereferenced straight away because GC in JS/ASP with ADO is a mess) after checking that the record set’s state isn’t 0 or from parameters of class adParamOutput (if the designers want to use output parameters to a stored proct and trust ADO/SQL Server not to screw it up). The record set can be closed and the recordset, command, and connection objects all overwritten with null at this point.

    Now I wonder if Dominic can tell me how his amazing string of junk is going to work against a system build properly, as described above? Or if Lee can tell me how passing whatever the form data is in a string parameter to an SP as above enables that string to be executed?

    Stop icon because I wish people would stop saying that avoiding being so totally stupid that your design is hopelessly bad and your website is hopelessly insecure in ways that the tiniest smidgeon of design awareness would avaoid is hard instead of admitting it's actually pretty easy.

  17. Lee Palmer

    @ac, @dominic

    Hi again. Just in case you return to this topic.

    In short, yes both descriptions above seem to be vunerable to SQL injection attack. Sorry. It took me a while to get back on this.

    In ac's case the keyword is append. It may be a stored proc but appending in a raw input strings still seems dangerous to me. I cannot prove it. Not familar enough with JS ADO to given an example.

    Dominic, I not sure how in_user, in_pwd get loaded with data. I see nothing to prevent raw input being executed by the SQL engine.

    Try ' ; drop tables; drop database; '

    in in_user

    .

    Cheers Lee

This topic is closed for new posts.

Other stories you might like