• TurboThy (unregistered)

    Security Through Obscurity at its finest.

  • Barfusslaeufer (unregistered) in reply to TurboThy

    This is so bad that I had to read it three times and now I'm not the first one to post any mor :/

  • sas (cs)

    I think "The Whiz" refers to the fact his code deserves to be urinated on. [:P] [+o(]

  • Jehos (cs)

    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...

  • sadmac (cs) in reply to Jehos

    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.

  • Maurits (cs)
    Alex Papadimoulis:
    <span style="color: rgb(0, 130, 0);">' takes order total and jumbles it mathematically</span> maskerAmount = ((((oTotal + 22) * 7 )) - 12) * 620<span style="font-family: monospace;"><br> </span>


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

    So the last digit of maskerAmount is always zero
  • Otis Mukinfus (unregistered) in reply to Jehos

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

  • spacey (unregistered) in reply to Otis Mukinfus

    with posts like these, Alex - you'll need to rename the site to:

    "the daily OMFG"

    -space

  • dubwai (cs) in reply to spacey

    <span style="COLOR: #000099">(</span>999999 - 100000 + 1)

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

  • Maurits (cs) in reply to Otis Mukinfus
    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 <span style="font-weight: bold;">and price</span> 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"
  • Charles Nadolski (cs) in reply to dubwai
    dubwai:

    <span style="color: rgb(0, 0, 153);">(</span>999999 - 100000 + 1)

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



    Because 900000 isn't obfuscated enough, silly ;)
  • whistler (unregistered)

    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. [:@]

  • loneprogrammer (cs)
    Alex Papadimoulis:

    <span style="color: rgb(0, 130, 0);">' takes order total and jumbles it mathematically</span> maskerAmount = ((((oTotal + 22) * 7 )) - 12) * 620

    <span style="color: rgb(0, 130, 0);"></span>



    The power of <span style="font-weight: bold;">mathematics</span> compels you!
    The power of <span style="font-weight: bold;">mathematics</span> compels you!

    *** projectile vomit pea soup ***

  • Apoch (cs) in reply to Maurits

    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 <span style="FONT-WEIGHT: bold">and price</span> 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.

  • Cthulhon (cs) in reply to Maurits
    <span id="_ctl0_PostForm_Reply"> 6. User clicks "Add to cart" link which passes product ID <span style="font-weight: bold;">and price</span> via querystring</span>

    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.
  • John Smallberries (cs)

    <font size="2">grrr...god I hate code like this.<br> <br> why would you even encrypt the total anyway?<br> </font>

  • Maurits (cs) in reply to Cthulhon
    Cthulhon:
    <span id="_ctl0_PostForm_Reply"> 6. User clicks "Add to cart" link which passes product ID <span style="font-weight: bold;">and price</span> via querystring</span>

    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.
  • Apoch (cs) in reply to Maurits

    Maurits:
    Cthulhon:
    <span id="_ctl0_PostForm_Reply"> 6. User clicks "Add to cart" link which passes product ID <span style="FONT-WEIGHT: bold">and price</span> via querystring</span>

    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.

  • Maurits (cs) in reply to Apoch
    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?
  • Apoch (cs) in reply to Maurits

    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.

  • Bustaz Kool (cs) in reply to loneprogrammer
    loneprogrammer:
    The power of <span style="FONT-WEIGHT: bold">mathematics</span> compels you!
    The power of <span style="FONT-WEIGHT: bold">mathematics</span> compels you!

    *** projectile vomit pea soup ***
    Now, that's funny!!  How funny?  F***in' funny!!!
  • Maurits (cs) in reply to Apoch
    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
  • Miszou (cs) in reply to Maurits

    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... [;)]

     

  • loneprogrammer (cs) in reply to Maurits
    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.

  • Maurits (cs) in reply to loneprogrammer
    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.
  • AnonymousCoder (unregistered) in reply to Maurits

    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?

    <span style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA">Relying on query string for any <em>significant</em>&nbsp;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?</span>

     

     

  • JThelen (cs) in reply to Maurits
    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.
  • spotcatbug (cs) in reply to JThelen

    Nobody beats The Whiz!

  • mizhi (cs) in reply to dubwai
    dubwai:

    <span style="color: rgb(0, 0, 153);">(</span>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?
  • noName (unregistered) in reply to mizhi


    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.
  • duck1123 (cs)

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

    [job] security through obscurity

  • uber1024 (cs)

    Well, Alex.  I think it's time to shut down your site.  This is never going to be topped, IMO.

  • Maurits (cs) in reply to AnonymousCoder
    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?

  • Spudley (unregistered) in reply to noName
    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.

  • Guayo2 (cs)

    <font size="1">Mortimer Armstrong:<br><p> <p>Where in the world have you been hiding?<br></p> <p>Really you were perfect.<br> I only wish I knew your secret,<br></p> <p>Who is this so called whiz?<br> <br></p> <p>Coworker:<br></p> <p>The user once spoke of an whiz,<br></p> <p>I used to dream he'd appear,<br> Now as I code I can sense him,<br></p> <p>And I know he's here.<br> Here in this asp-snip he calls me softly,<br></p> <p>Somewhere inside...hiding.<br> Somehow I know, he's always with me,<br></p> <p>he's the unseen [mathematical] genius.<br> <br></p> <p>Mortimer Armstrong:<br></p> <p>My friend you must have been dreaming,<br></p> <p>Stories like this can't come true<br> My friend you're talking in riddles,<br></p> <p>And it's not like you!<br> <br></p> <p>Coworker:<br></p> <p>Whiz of The System,<br></p> <p>l33t h4x0r and Guardian,<br></p> <p>Grant to me you glory!<br> <br></p> <p>Mortimer Armstrong:<br></p> <p>Who is this Whiz?<br></p> <p>This...<br> <br></p> <p>Both:<br></p> <p>Whiz of The System,<br></p> <p>Hide no longer, <br></p> <p>secret and strange whiz<br> <br></p> <p>Coworker:<br></p> <p>He's with me even now<br> <br></p> <p>Mortimer Armstrong: <br></p> <p>Your hands are cold<br> <br></p> <p>Coworker:<br></p> <p>All around me<br> <br></p> <p>Mortimer Armstrong:<br></p> <p>Your face, my friend, it's white<br> <br></p> <p>Coworker:<br></p> <p>It frightens me<br> [...]</font>

  • Maurits (cs) in reply to Guayo2

    Keep your hand at the level of your eyes ;)

  • Guayo2 (cs) in reply to Maurits
    Maurits:
    Keep your hand at the level of your eyes ;)


    I suppose Mortimer would like to practice some punjab lasso techniques on "The Whiz"
  • Golly (unregistered) in reply to loneprogrammer
    loneprogrammer:
    The power of <span style="font-weight: bold;">mathematics</span> compels you!
    The power of <span style="font-weight: bold;">mathematics</span> compels you!

    *** projectile vomit pea soup ***


    Hahaha, oh man that's damn funny!
  • phelyan (cs) in reply to spotcatbug

    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.

  • Ben Dover (unregistered) in reply to spotcatbug
    spotcatbug:
    Nobody beats The Whiz!


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

    Now, to re-write all this code:

    Session["price"] = price

    Done!

  • The Whiz (unregistered)

    Hey this looks like my code!!!!!

  • Jon Limjap (cs) in reply to The Whiz

    The Whiz is Evil!!!!

  • Pax (unregistered) in reply to whistler

    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.


  • dhromed (cs) in reply to Pax

    Real mathemawizards use complex numbers to encrypt their pricetags.

  • No obscurity needed (unregistered) in reply to TurboThy

    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.

  • Xepol (cs)

    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...

  • Xepol (cs) in reply to Xepol
    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??

  • Rank Amateur (cs)

    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

  • Adi (unregistered)

    If maskerAmount is the "masked" amount and maskerDummy is "throw someone off", why is maskerDummy being passed in the Response?

  • b1xml2 (unregistered)

    <span style="font-family: verdana;">There are some fundamental rules broken by the code snippet.<br> <br> </span>

    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: <span style="font-weight: bold;">track </span>to hold the actual amount and <span style="font-weight: bold;">tot </span>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.

Leave a comment on “The Phantom of The System”

Log In or post as a guest

Replying to comment #:

« Return to Article