Comment On The Phantom of The System

Mortimer Armstrong and his coworker had always known about The System: a gigantic order entry/processing applications written entirely in ASP/VBScript. The System was so fragile that something as simple as a misplaced "double-click" could bring the whole thing down. The code churning within The System was so intricate and complex that only "The Whiz" (who, consequently, was also the author of The System) could possibly understand and maintain it. After The Whiz had left the company, The System fell into Mortimer's coworker's lap. Amongst countless other things, one thing that he was having such a hard time figuring out was the significance of the mysterious numbers 22, 7, -12, and 620 strewn throughout the code. Then he found this. Amidst 1600 lines VBScript order validation/processing code. With not a single line containing anything even resembling a function or subroutine. [expand full text]
« PrevPage 1 | Page 2Next »

Re: The Phantom of The System

2005-08-02 13:54 • by TurboThy
Security Through Obscurity at its finest.

Re: The Phantom of The System

2005-08-02 13:56 • by Barfusslaeufer
39678 in reply to 39677
This is so bad that I had to read it three times and now I'm not the first one to post any mor :/

Re: The Phantom of The System

2005-08-02 13:56 • by sas
I think "The Whiz" refers to the fact his code deserves to be urinated on. [:P] [+o(]

Re: The Phantom of The System

2005-08-02 13:56 • by Jehos

Funny how encryption just escapes some people.  If you're worried about exposing values, you could just encrypt what you want to hide then decrypt it on the receiving page to reveal its true beauty, just like the poor Phantom of the Opera.


Or you could, you know, not pass values in the querystring...

Re: The Phantom of The System

2005-08-02 13:58 • by sadmac
39681 in reply to 39680
Wow. Just wow.



Note: for full effect from this particular WTF, go find the title music from Clockwork Orange and listen as you read the code.

Re: The Phantom of The System

2005-08-02 14:00 • by Maurits
Alex Papadimoulis:
' takes order total and jumbles it mathematically
maskerAmount = ((((oTotal + 22) * 7 )) - 12) * 620





The worst part is, this is exactly equivalent to:

maskerAmount = 4340 * oTotal + 88040



So the last digit of maskerAmount is always zero

Re: The Phantom of The System

2005-08-02 14:14 • by Otis Mukinfus
39684 in reply to 39680
Dammit!  Now I'll have to go back and change all my code to not use querystring :o(

Re: The Phantom of The System

2005-08-02 14:18 • by spacey
39685 in reply to 39684
with posts like these, Alex - you'll need to rename the site to:



"the daily OMFG"



-space

Re: The Phantom of The System

2005-08-02 14:25 • by dubwai
39686 in reply to 39685

(999999 - 100000 + 1)


What's the point of doing that calcuation not only once but mutliple times?

Re: The Phantom of The System

2005-08-02 14:26 • by Maurits
39687 in reply to 39684
Anonymous:
Dammit!  Now I'll have to go back and change all my code to not use querystring :o(




Nothing wrong with using the querystring... as long as you verify it independently.



For example....

1. User pulls up "view product" page

2. User notes price - $50

3. User reads description

Time passes...

4. Manager changes price to $60

Time passes...

5. User decides "all right, I'll buy it"

6. User clicks "Add to cart" link which passes product ID and price via querystring

7. "add to cart" page compares price from query string and database and notices they're different

8. "add to cart" page displays helpful message to user along the lines
of "The price of this product has recently changed to $60.  Add to
cart anyway? OK / Cancel"

Re: The Phantom of The System

2005-08-02 14:30 • by Charles Nadolski
39688 in reply to 39686
dubwai:

(999999 - 100000 + 1)


What's the point of doing that calcuation not only once but mutliple times?





Because 900000 isn't obfuscated enough, silly ;)

Re: The Phantom of The System

2005-08-02 14:46 • by whistler
This is the classical definition of encraption.  When the same amount is sent through this routine multiple times, only one part of the query string will remain constant -- the 7th through 12th digits of track.  Now an attacker just needs to collect several of these values for different purchases and perform a linear regression to find they all fall on the line y=4340x+88040.  It's then trivial to find x is the purchase amount, and modify it accordingly (depending, of course, on the context).  Security by obscurity, indeed. [:@]

Re: The Phantom of The System

2005-08-02 14:47 • by loneprogrammer
Alex Papadimoulis:

' takes order total and jumbles it mathematically
maskerAmount = ((((oTotal + 22) * 7 )) - 12) * 620



The power of mathematics compels you!
The power of mathematics compels you!

*** projectile vomit pea soup ***

Re: The Phantom of The System

2005-08-02 14:51 • by Apoch
39691 in reply to 39687

Maurits:
Anonymous:
Dammit!  Now I'll have to go back and change all my code to not use querystring :o(


Nothing wrong with using the querystring... as long as you verify it independently.

For example....
1. User pulls up "view product" page
2. User notes price - $50
3. User reads description
Time passes...
4. Manager changes price to $60
Time passes...
5. User decides "all right, I'll buy it"
6. User clicks "Add to cart" link which passes product ID and price via querystring
7. "add to cart" page compares price from query string and database and notices they're different
8. "add to cart" page displays helpful message to user along the lines of "The price of this product has recently changed to $60.  Add to cart anyway? OK / Cancel"


This smells of overengineering if you ask me - especially in nontrivial systems where there's a lot more to consider about an item than just price. Just pass the product ID via querystring and present the user with a price totals page before they confirm their purchase. Even better, internally track the price that they "picked up" the item for in their shopping cart and do some sanity validation on that price (e.g. it is less than 4 hours old, etc.) and just charge them that price. Works out great for all concerned.

Re: The Phantom of The System

2005-08-02 14:51 • by Cthulhon
39692 in reply to 39687

6. User clicks "Add to cart" link which passes product ID and price via querystring


Why?  if you're just going to check against the DB later, why pass
the price?  Better to do something like pass the timestamp and
check it against when the product was updated.

Re: The Phantom of The System

2005-08-02 14:54 • by John Smallberries
grrr...god I hate code like this.



why would you even encrypt the total anyway?

Re: The Phantom of The System

2005-08-02 14:59 • by Maurits
39694 in reply to 39692
Cthulhon:

6. User clicks "Add to cart" link which passes product ID and price via querystring


Why?  if you're just going to check against the DB later, why pass
the price?  Better to do something like pass the timestamp and
check it against when the product was updated.





Because the manager could change his mind and set it back to $50
again.  This would lead to the user getting a confusing message
like "The price has changed to $50" when it already was $50.  Or
maybe the manager just changed an internal field on the Products table,
like the accounting code.

Re: The Phantom of The System

2005-08-02 15:03 • by Apoch
39695 in reply to 39694

Maurits:
Cthulhon:
6. User clicks "Add to cart" link which passes product ID and price via querystring

Why?  if you're just going to check against the DB later, why pass the price?  Better to do something like pass the timestamp and check it against when the product was updated.


Because the manager could change his mind and set it back to $50 again.  This would lead to the user getting a confusing message like "The price has changed to $50" when it already was $50.  Or maybe the manager just changed an internal field on the Products table, like the accounting code.


The YAGNI principle was invented specifically for this kind of thing. In practice, this is not a genuine problem. I've written a couple of web-store applications and my current employer shares an office suite with a company whose sole business is building web-store apps. Any user who doesn't check their totals on the checkout screen before blindly throwing their credit card number at a web site deserves to get snipped out of the $10 price difference - and customer service departments exist for smoothing over the problem. I'd be willing to lay out a decent wad of cash that a large amount of WTFery is generated by over-engineering to account for such non-issues.

Re: The Phantom of The System

2005-08-02 15:19 • by Maurits
39696 in reply to 39695
Apoch:

Any user who doesn't check their totals on
the checkout screen before blindly throwing their credit card number at
a web site deserves to get snipped out of the $10 price difference





And what if the total changes between when they load the "checkout"
page and when they submit the "checkout" page?  Do you check that?

Re: The Phantom of The System

2005-08-02 15:21 • by Apoch
39697 in reply to 39696

Maurits:
And what if the total changes between when they load the "checkout" page and when they submit the "checkout" page?  Do you check that?


Since you missed it the first time:


Apoch:
Even better, internally track the price that they "picked up" the item for in their shopping cart and do some sanity validation on that price (e.g. it is less than 4 hours old, etc.) and just charge them that price. Works out great for all concerned.

Re: The Phantom of The System

2005-08-02 15:24 • by Bustaz Kool
39698 in reply to 39690
loneprogrammer:
The power of mathematics compels you!
The power of mathematics compels you!

*** projectile vomit pea soup ***
Now, that's funny!!  How funny?  F***in' funny!!!

Re: The Phantom of The System

2005-08-02 15:37 • by Maurits
39699 in reply to 39697
Apoch:

Maurits:
And what if the total
changes between when they load the "checkout" page and when they submit
the "checkout" page?  Do you check that?


Since you missed it the first time:


Apoch:
Even better, internally track the price that
they "picked up" the item for in their shopping cart and do some sanity
validation on that price (e.g. it is less than 4 hours old, etc.) and
just charge them that price. Works out great for all concerned.





No, you misunderstand [:)]  I'm fine with letting the user buy
something at the price that was on the shelf at the time they put the
item in their cart, even if we changed it by the time they got to the
register.  I do that myself in my homegrown shopping cart.



But I do pass the total from the "gather credit card" page to the
"process credit card" page, because I worry about the user slipping
something into the cart after I've swiped their card and before they
leave the register.



1. User goes to checkout page with a stick of gum in their cart - total is $0.10

2. In another browser, user adds a big-screen TV to their cart

3. User pays $0.10 and walks out with their gum and their TV

Re: The Phantom of The System

2005-08-02 15:58 • by Miszou
39702 in reply to 39699

Maurits:

1. User goes to checkout page with a stick of gum in their cart - total is $0.10
2. In another browser, user adds a big-screen TV to their cart
3. User pays $0.10 and walks out with their gum and their TV


Does that really work? Just askin', you know. Might be something to look out for in my own code. Yeah, that's it... [;)]


 

Re: The Phantom of The System

2005-08-02 16:01 • by loneprogrammer
39703 in reply to 39699
Maurits:
1. User goes to checkout page with a stick of gum in their cart - total is $0.10

2. In another browser, user adds a big-screen TV to their cart

3. User pays $0.10 and walks out with their gum and their TV


Try this at amazon.com and you just get sent back to the "confirm order" screen.



Passing anything important through the query string is a WTF. 
What stops someone from sending any query string they want? 
Nothing!



You should lock the shopping cart on the server, or check for new items
in the cart before placing the order.  Never trust any data that
the client sends you.



Re: The Phantom of The System

2005-08-02 16:27 • by Maurits
39704 in reply to 39703
loneprogrammer:
check for new items
in the cart before placing the order


Well, I do.  Specifically, I compare the total I get from the form
against the total I get by adding up the product prices currently in
their cart.



So they could switch out products all they want, as long as their total
remains the same.  They are charged for - and their receipt
contains - the products in their cart at the time I process their card,
not necessarily what they had in their cart when the "enter credit card
info" page was loaded.

Re: The Phantom of The System

2005-08-02 16:33 • by AnonymousCoder
39705 in reply to 39682

Maurits:

The worst part is, this is exactly equivalent to:
maskerAmount = 4340 * oTotal + 88040


It's actually: maskerAmount = 4340 * oTotal + 80600


I wonder if there's even bigger WTF behind this code. Why did he feel that   total amount needs to be "masked" in the first place. From the code it looks like, it's being redirected to thankyou.asp, what is a big deal having total in query string on that page? Maybe it’s over engineering as some suggest. Or maybe the query string value is the actual value that is being charged to user credit card?


Relying on query string for any significant input is in general a WTF; what would happen if a user changed qs values and resubmitted this page with maskerAmount=0 or maskerAmount=xxxWTFxxx?


 


 

Re: The Phantom of The System

2005-08-02 16:45 • by JThelen
39708 in reply to 39704
Maurits:
loneprogrammer:
check for new items
in the cart before placing the order


Well, I do.  Specifically, I compare the total I get from the form
against the total I get by adding up the product prices currently in
their cart.



So they could switch out products all they want, as long as their total
remains the same.  They are charged for - and their receipt
contains - the products in their cart at the time I process their card,
not necessarily what they had in their cart when the "enter credit card
info" page was loaded.




I'd highly reccomend changing that.  It's practically begging for
a mischarge lawsuit, since the possibility of billing for goods not
received exists, and as you seem to be saying, is exceptionally easy.



While I think Apoch can take YAGNI, and shove it where the sun doesn't
shine along with the rest of eXtreme Programming, he certainly has a
point regarding the verification of goods in the cart against their
current price at the time of checkout.

Re: The Phantom of The System

2005-08-02 17:14 • by spotcatbug
39709 in reply to 39708
Nobody beats The Whiz!

Re: The Phantom of The System

2005-08-02 17:20 • by mizhi
39710 in reply to 39686
dubwai:

(999999 - 100000 + 1)


What's the point of doing that calcuation not only once but mutliple times?





You are missing the larger picture: what is the point of this entire bit of code?

Re: The Phantom of The System

2005-08-02 17:43 • by noName
39712 in reply to 39710




You are missing the larger picture: what is the point of this entire bit of code?




Job security. Once you manage to slip such a beast into production you
can't be fired. And if you leave the company by your own decission you
can charge for consulting again and again, or have some revenge and
leave them high and dry if you feel like it.

Re: The Phantom of The System

2005-08-02 17:44 • by duck1123

I'm confused. Is he trying to protect "The System" from End-Users or other developers?


[job] security through obscurity

Re: The Phantom of The System

2005-08-02 18:01 • by uber1024
Well, Alex.  I think it's time to shut down your site.  This is never going to be topped, IMO.

Re: The Phantom of The System

2005-08-02 18:07 • by Maurits
39717 in reply to 39705
Anonymous:

Maurits:

The worst part is, this is exactly equivalent to:
maskerAmount = 4340 * oTotal + 88040


It's actually: maskerAmount = 4340 * oTotal + 80600







Are you sure?


Re: The Phantom of The System

2005-08-02 18:11 • by Spudley
39718 in reply to 39712
Anonymous:
you can't be fired. And if you leave the company by your own decission you can charge for consulting again and again, or have some revenge and leave them high and dry if you feel like it.


Hmmm.... revenge may be good, but employment references are better.

some lyrics

2005-08-02 19:06 • by Guayo2
Mortimer Armstrong:


Where in the world have you been hiding?


Really you were perfect.

I only wish I knew your secret,


Who is this so called whiz?




Coworker:


The user once spoke of an whiz,


I used to dream he'd appear,

Now as I code I can sense him,


And I know he's here.

Here in this asp-snip he calls me softly,


Somewhere inside...hiding.

Somehow I know, he's always with me,


he's the unseen [mathematical] genius.




Mortimer Armstrong:


My friend you must have been dreaming,


Stories like this can't come true

My friend you're talking in riddles,


And it's not like you!




Coworker:


Whiz of The System,


l33t h4x0r and Guardian,


Grant to me you glory!




Mortimer Armstrong:


Who is this Whiz?


This...




Both:


Whiz of The System,


Hide no longer,


secret and strange whiz




Coworker:


He's with me even now




Mortimer Armstrong:


Your hands are cold




Coworker:


All around me




Mortimer Armstrong:


Your face, my friend, it's white




Coworker:


It frightens me

[...]


Re: some lyrics

2005-08-02 19:08 • by Maurits
39723 in reply to 39722
Keep your hand at the level of your eyes ;)

Re: some lyrics

2005-08-02 19:29 • by Guayo2
39725 in reply to 39723
Maurits:
Keep your hand at the level of your eyes ;)




I suppose Mortimer would like to practice some punjab lasso techniques on "The Whiz"

Re: The Phantom of The System

2005-08-02 21:24 • by Golly
39731 in reply to 39690
loneprogrammer:
The power of mathematics compels you!
The power of mathematics compels you!

*** projectile vomit pea soup ***




Hahaha, oh man that's damn funny!

Re: The Phantom of The System

2005-08-02 21:49 • by phelyan
39733 in reply to 39709

spotcatbug:
Nobody beats The Whiz!


I'm sure there's a few people out there by now who would want to. With clue-by-fours.

Re: The Phantom of The System

2005-08-02 22:42 • by Ben Dover
39735 in reply to 39709
spotcatbug:
Nobody beats The Whiz!




Heheh... kudos for the Seinfeld reference...



Now, to re-write all this code:



Session["price"] = price



Done!



Re: The Phantom of The System

2005-08-02 22:56 • by The Whiz
Hey this looks like my code!!!!!

Re: The Phantom of The System

2005-08-02 23:10 • by Jon Limjap
39738 in reply to 39736
The Whiz is Evil!!!!

Re: The Phantom of The System

2005-08-03 00:14 • by Pax
39740 in reply to 39689
Bah! That's easily fixed - you just need to use higher-order
polynomials.  If, instead of ax+b, you use
ax^100+bx^99+cx^88+...+d, it will require 100 (or 101, I can't
remember) orders to solve the polynomial values.



Obviously, you can make this even harder to attack by using massive
polynomial coefficients.  And, when the customers find that each
order on the net is taking 2.7 years to complete, they'll go elsewhere
:-).



It's a joke, Joyce.





Re: The Phantom of The System

2005-08-03 04:44 • by dhromed
39751 in reply to 39740
Real mathemawizards use complex numbers to encrypt their pricetags.

Re: The Phantom of The System

2005-08-03 04:58 • by No obscurity needed
39753 in reply to 39677
Sometimes we need to use passing parameters through url (or post) for
systems that have nothing to do with each other. The anti-tempering
solution was easy to implement without obsuring anything - we calculate
md5 signature for url + "a secret part" and append it as the end of the
url as the last parameter. Works like a charm.

Re: The Phantom of The System

2005-08-03 05:24 • by Xepol
What amazes me more than the code is that in all the replies so far about ASP code, there has only been one reference to the server side only session object.

Suddenly, the Wizz.

Uh, since it is (APPARENTLY) only a thank you page, I'm not entirely sure why it is even really required to be so obtuse, but hey, whatever turns your crank.

Interesting technique to ensure that he can always pull out the price tho - you have to at least respect the thought put into the random padding, even if you can't admire his litteracy skills reading the asp manuals...

Re: The Phantom of The System

2005-08-03 05:29 • by Xepol
39755 in reply to 39754
Xepol:
Suddenly, the Wizz.


Speaking of litteracy skills.. :$

I was GOING to say, suddenly the wizz doesn't seem to be so alone... (after all, if everyone here can ignore the session object, why shouldn't he?)

As an interesting side note, and a totally different WTF, who set the limit limit for editing posts to obscenely small time limits less than 10 seconds??

Re: The Phantom of The System

2005-08-03 08:26 • by Rank Amateur

Ooooo. u1tr4 l33t encryption by linear transformation. Julius Caesar would be completely baffled.


Yeah, it's overengineered. You never need more than ROT13 for anything.


--Rank

Re: The Phantom of The System

2005-08-03 08:42 • by Adi
If maskerAmount is the "masked" amount and maskerDummy is "throw someone off", why is maskerDummy being passed in the Response?

Re: The Phantom of The System

2005-08-03 08:49 • by b1xml2
There are some fundamental rules broken by the code snippet.





  1. Never expose private data via the Query String. This particularly
    applies to sensitive data as well as data that is used to reconstruct a
    portion of the UI that the user sees.

  2. By obfuscating the total amount and by attempting to mislead
    anyone that is curious enough to modify the url, the author has
    constructed two parameters: track to hold the actual amount and tot to
    mislead. This in itself indicates that the author is aware of the
    consequences of breaking #1 if not knowing the actual rule itself.

  3. Anyone trying to defend such methodology (as some have attempted
    to argue that it is reasonable to send the data via the query string)
    merely demonstrates a lack of understanding of what it takes to make
    secure and functional web applications.

  4. Protecting the data from tampering can take many forms: one could
    store the data in SQL Server with a timestamp or guid to provide the
    reference key. Alternatively, one could store it in the Session object
    (or in ASP.NET, one could store it in the ViewState and have enableMac
    property set to true)


Invariably, any web developer who is still doing what this snippet
does, exposing private data in the querystring ought to be publicly
humiliated. They just give web developers a bad name and by no small
measure, we have quite a significant mass of web programmers who are
neither programmers of any decent distinction nor proponents of any
worthwhile methodology.

« PrevPage 1 | Page 2Next »

Add Comment