Re: math variable security [VERY LONG]

This WebDNA talk-list message is from

2000


It keeps the original formatting.
numero = 33496
interpreted = N
texte = Bob - I have been out of the office for the past few days and am trying to keep up with my e-mail from home. I wanted to respond to your messages not because I am picking on you (although it may seem that way at first), but because this is exactly the reason I argued that the secure=f was unnecessary and in fact a bad addition to WebDNA.I don't know if the code you posted is production or you just whipped it out to demonstrate your point, but I see several failures of logic and general design problems that I hope I can correct. This will be a long message because I want to try and lay out some basic thoughts first before tackling your code. Some of it may seem incredibly basic to most of the readers on this list, but I encourage everyone to follow my logic though, so you know where I am coming from later.HTML is, by its very nature, stateless; in other words, a user can hit any page on your site in any order, and can leave your site at any point. Most of the time, we can program our sites so that the user often follows some set of paths through it, but there is no way to force a specific path (short of cascading [protect] pages). True, you can use realms to limit the scope of where the user can go, but that is basically beside the point here.HTML is also designed to operate under a client/server model; the user enters some data on one page and the server processes it prior to serving up the next page (which can even be the exact same template). Form-variables are designed to carry state information between pages. They can be present inside a
tag or present as part of the URL itself ( ...page.tpl?command=explode). They are in essence client-side variables; the user can change them at will (and do things to them you hadn't considered). Form variables are by their very nature insecure.WebDNA [text] and [math] variables, on the other hand, are server-side, intended to be used within the logical page, typically to simplify processing. Any manipulation of the value of said variables occurs solely on the server; hence they are by nature secure. To use the new context metaphor, [text] and [math] variables have a page context (and I will now refer to them jointly as page variables); they spring into life at the point they are first used on the page and exist until the bottom of that template. They are not available on the next page, unless you pass them as form variables (in programming lingo, they are local not global variables).Prior to version 4.0, it was possible to share a variable name between a form variable and a page variable; the user-defined form variable would be used as the initial value for the now defined page variable. If the user did not pass any value for that form variable, the initial value is the string [varname] where varname is the name of the variable. Ken (and others) have used this behavior to quickly initialize all of their page variables at the top, so any tests on the page can be versus null rather than having to test definedness. I view this as sloppy programming because it ignores the changes that a [malicious] user can make to form variables. Just imagine the damage a user could do by replacing a form variable with [shell]format c: /quick[/shell]; note: this will work do anything because WebDNA does not do an implicit [interpret]; but, if you ever thought about passing WebDNA code from page to page via form variables, this should persuade you not to.Now, with all that text behind us, I am now going to analyze Bob's code and make some concrete suggestions for changes. See inline comments below...Bob Minor wrote: > > [text secure=f&multi=t]fname=&lname=[/text] > [math secure=f]error=0[/math]This is an unneccessary assignment as we shall see below, since the variable [error] is never used on the first page as a math variable. The fact that it is used as a math variable on the second page is immaterial to the discussion. In fact, all variables are passed between templates as form variables, even under the 3.x model. Each template is defined separately from the other; it is not like a language like BASIC where two modules can share a common global variable.> > [showif [error]>1]As near as I can tell, this test is wrong; if the user misses a single field, the redirect will happen [error]>0, but neither showif [error]>1 will fire.> [showif[fname]=]oops this one is blank[/showif][/showif]
> [showif [error]>1][showif > [lname]=]oops this one is blank[/showif][/showif]
> >
Note that on this first page, the variable [error] is only used in tests; no calculations are performed and the value is not changed (except for the initialize, which I said is not needed). [error] is in fact a form variable, used to carry the error state from the second page to the first.> > then on my submitted page I do: > [formvariables] > [showif [value]=][math show=f]error=error+1[/math][/showif]Here, Bob has just defined a math variable, but in such a way that the variable is never initialized. The previous page did not pass any form variable called error, so the first formvariable with a null value sets it to error=undef+1, which WebCat cleverly reduces to 1. This is what I have repeatedly stated is lazy programming. All page variable should be initialized to sensible values (usually 0 for math and null for text), and all form variables should be tested to see that they contain a value that is reasonable.> [/formvariables]Here, if the user did not supply a value for lname and fname, error=2; if the user missed either but not both, error=1.> [showif [error]>0]This will show if either or both fields are missing.> [redirect > thispage.tpl?error=[error][formvariables]&[name]=[value][/formvariables]]Here, Bob is using form variables to pass back the error state, as well as any existing values, to the initial page. But as I stated above, if the user only misses one value, the Oops... warning will not show at all.> [showif] Note that this should be [/showif]> [fname] [lname] you done good digging through that form. > The problem here is that Bob is trying to use the [error] variable to flag which field is missing, but is really only flagging that there is _some_ field missing. To redesign this page, I am going to use WebDNA 3.x logic, nothing fancy. I am going to walk though how I would design this page, rather than just laying it out in a finished form.I am going to make the following assumptions about how the tempaltes flows: 1) the first page is stand-alone, i.e. it is not initially called as anything except thispage.tpl (i.e. no URL variables or POST form variables).2) the program should note which field is missing and prompt that field alone, as well as retaining any previously entered values.3) Bob actually intended the user to key some values into input fields. As it stands now, these pages do nothing visably, since the user is never given a chance to key anything, so both fields will forever be blank, unless they were being passed from some other template. I'm going to ignore that because that would just require a third page for data entry.Now, for the first pass at thispage.tpl:
The clever people on this list will notice that this is, in fact, pure HTML. I believe this is the appropriate place to start, since it will drive the initial interaction with the user. It is also what the page should resolve to, once the WebDNA is entered (i.e. everything else will have hideif/showif's).The second page (nextpage.tpl) will receive 2 defined form variables, either or both which can be null. [text show=f]missing=[/text][!]always init vars[/!][formvariables] [showif [value]=] [text show=f]missing=missing'[name][/text] [/showif] [/formvariables][showif [missing]!] [redirect thispage.tpl?missing=[missing][formvariables]&[name]=[value][/formvariables]] [/showif] [fname] [lname] you done good digging through that form. This is pretty much the same as Bob's page, but I changed the name of the error variable and what I am doing with it. What I did will mean that if lname is not entered, then missing='lname; if fname is not entered, missing='fname; and if both are not entered missing='fname'lname. The delimiter character can be anything you want it to be that is not an alphabetic charatcer.Now, the first can be entered upon the redirect, and, in this case, will be passed exactly three form variables: missing, fname, and lname. Note that due to the clever coding that Bob did with the redirect, this code can actually be used to check any number of variables. I would actually use it as an include file and change the thispage.tpl into a parameter for the include file, i.e. [include file=checkup.inc&template=thispage.tpl]In any event, let's return to the first page and finish it with the appropriate tests:
[showif [missing]~fname]oops this one is blank[/showif] [showif [missing]~lname]oops this one is blank[/showif]
Note that this form will now operate as I believe Bob intended, yet it does not need secure=f, nor any complicated hoops to deal with the field testing. In fact, since I separated the form initialization code from the blank field warning, you could also call this template as firstpage.tpl?fname=my&lname=name and still function as it should.If I had a lot more time, I would state categorically that any set of pages that rely on secure=f can be easily rewritten to not require it,and that I could do it on demand. I know that I have never needed to use the variable overloading feature, and I have yet to see any code that convinced me it is useful. I know that there are some schools of thought that suggest that all form variables (client side) be named with a preceeding underscore (_fname), so that it is painfully obvious that it is not the same thing as a similarly named text (server side) variable (fname).Hope this helps someone...John Peacock------------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: To switch to the DIGEST mode, E-mail to Web Archive of this list is at: http://search.smithmicro.com/ Associated Messages, from the most recent to the oldest:

    
  1. Re: math variable security [VERY LONG] (John Peacock 2000)
Bob - I have been out of the office for the past few days and am trying to keep up with my e-mail from home. I wanted to respond to your messages not because I am picking on you (although it may seem that way at first), but because this is exactly the reason I argued that the secure=f was unnecessary and in fact a bad addition to WebDNA.I don't know if the code you posted is production or you just whipped it out to demonstrate your point, but I see several failures of logic and general design problems that I hope I can correct. This will be a long message because I want to try and lay out some basic thoughts first before tackling your code. Some of it may seem incredibly basic to most of the readers on this list, but I encourage everyone to follow my logic though, so you know where I am coming from later.HTML is, by its very nature, stateless; in other words, a user can hit any page on your site in any order, and can leave your site at any point. Most of the time, we can program our sites so that the user often follows some set of paths through it, but there is no way to force a specific path (short of cascading [protect] pages). True, you can use realms to limit the scope of where the user can go, but that is basically beside the point here.HTML is also designed to operate under a client/server model; the user enters some data on one page and the server processes it prior to serving up the next page (which can even be the exact same template). Form-variables are designed to carry state information between pages. They can be present inside a
tag or present as part of the URL itself ( ...page.tpl?command=explode). They are in essence client-side variables; the user can change them at will (and do things to them you hadn't considered). Form variables are by their very nature insecure.WebDNA [text] and [math] variables, on the other hand, are server-side, intended to be used within the logical page, typically to simplify processing. Any manipulation of the value of said variables occurs solely on the server; hence they are by nature secure. To use the new context metaphor, [text] and [math] variables have a page context (and I will now refer to them jointly as page variables); they spring into life at the point they are first used on the page and exist until the bottom of that template. They are not available on the next page, unless you pass them as form variables (in programming lingo, they are local not global variables).Prior to version 4.0, it was possible to share a variable name between a form variable and a page variable; the user-defined form variable would be used as the initial value for the now defined page variable. If the user did not pass any value for that form variable, the initial value is the string [varname] where varname is the name of the variable. Ken (and others) have used this behavior to quickly initialize all of their page variables at the top, so any tests on the page can be versus null rather than having to test definedness. I view this as sloppy programming because it ignores the changes that a [malicious] user can make to form variables. Just imagine the damage a user could do by replacing a form variable with [shell]format c: /quick[/shell]; note: this will work do anything because WebDNA does not do an implicit [interpret]; but, if you ever thought about passing WebDNA code from page to page via form variables, this should persuade you not to.Now, with all that text behind us, I am now going to analyze Bob's code and make some concrete suggestions for changes. See inline comments below...Bob Minor wrote: > > [text secure=f&multi=t]fname=&lname=[/text] > [math secure=f]error=0[/math]This is an unneccessary assignment as we shall see below, since the variable [error] is never used on the first page as a math variable. The fact that it is used as a math variable on the second page is immaterial to the discussion. In fact, all variables are passed between templates as form variables, even under the 3.x model. Each template is defined separately from the other; it is not like a language like BASIC where two modules can share a common global variable.> > [showif [error]>1]As near as I can tell, this test is wrong; if the user misses a single field, the redirect will happen [error]>0, but neither showif [error]>1 will fire.> [showif[fname]=]oops this one is blank[/showif][/showif]
> [showif [error]>1][showif > [lname]=]oops this one is blank[/showif][/showif]
> >
Note that on this first page, the variable [error] is only used in tests; no calculations are performed and the value is not changed (except for the initialize, which I said is not needed). [error] is in fact a form variable, used to carry the error state from the second page to the first.> > then on my submitted page I do: > [formvariables] > [showif [value]=][math show=f]error=error+1[/math][/showif]Here, Bob has just defined a math variable, but in such a way that the variable is never initialized. The previous page did not pass any form variable called error, so the first formvariable with a null value sets it to error=undef+1, which WebCat cleverly reduces to 1. This is what I have repeatedly stated is lazy programming. All page variable should be initialized to sensible values (usually 0 for math and null for text), and all form variables should be tested to see that they contain a value that is reasonable.> [/formvariables]Here, if the user did not supply a value for lname and fname, error=2; if the user missed either but not both, error=1.> [showif [error]>0]This will show if either or both fields are missing.> [redirect > thispage.tpl?error=[error][formvariables]&[name]=[value][/formvariables]]Here, Bob is using form variables to pass back the error state, as well as any existing values, to the initial page. But as I stated above, if the user only misses one value, the Oops... warning will not show at all.> [showif] Note that this should be [/showif]> [fname] [lname] you done good digging through that form. > The problem here is that Bob is trying to use the [error] variable to flag which field is missing, but is really only flagging that there is _some_ field missing. To redesign this page, I am going to use WebDNA 3.x logic, nothing fancy. I am going to walk though how I would design this page, rather than just laying it out in a finished form.I am going to make the following assumptions about how the tempaltes flows: 1) the first page is stand-alone, i.e. it is not initially called as anything except thispage.tpl (i.e. no URL variables or POST form variables).2) the program should note which field is missing and prompt that field alone, as well as retaining any previously entered values.3) Bob actually intended the user to key some values into input fields. As it stands now, these pages do nothing visably, since the user is never given a chance to key anything, so both fields will forever be blank, unless they were being passed from some other template. I'm going to ignore that because that would just require a third page for data entry.Now, for the first pass at thispage.tpl:
The clever people on this list will notice that this is, in fact, pure HTML. I believe this is the appropriate place to start, since it will drive the initial interaction with the user. It is also what the page should resolve to, once the WebDNA is entered (i.e. everything else will have hideif/showif's).The second page (nextpage.tpl) will receive 2 defined form variables, either or both which can be null. [text show=f]missing=[/text][!]always init vars[/!][formvariables] [showif [value]=] [text show=f]missing=missing'[name][/text] [/showif] [/formvariables][showif [missing]!] [redirect thispage.tpl?missing=[missing][formvariables]&[name]=[value][/formvariables]] [/showif] [fname] [lname] you done good digging through that form. This is pretty much the same as Bob's page, but I changed the name of the error variable and what I am doing with it. What I did will mean that if lname is not entered, then missing='lname; if fname is not entered, missing='fname; and if both are not entered missing='fname'lname. The delimiter character can be anything you want it to be that is not an alphabetic charatcer.Now, the first can be entered upon the redirect, and, in this case, will be passed exactly three form variables: missing, fname, and lname. Note that due to the clever coding that Bob did with the redirect, this code can actually be used to check any number of variables. I would actually use it as an include file and change the thispage.tpl into a parameter for the include file, i.e. [include file=checkup.inc&template=thispage.tpl]In any event, let's return to the first page and finish it with the appropriate tests:
[raw][fname][/raw]]value=[fname][/hideif]> [showif [missing]~fname]oops this one is blank[/showif] [raw][lname][/raw]]value=[lname][/hideif]> [showif [missing]~lname]oops this one is blank[/showif]
Note that this form will now operate as I believe Bob intended, yet it does not need secure=f, nor any complicated hoops to deal with the field testing. In fact, since I separated the form initialization code from the blank field warning, you could also call this template as firstpage.tpl?fname=my&lname=name and still function as it should.If I had a lot more time, I would state categorically that any set of pages that rely on secure=f can be easily rewritten to not require it,and that I could do it on demand. I know that I have never needed to use the variable overloading feature, and I have yet to see any code that convinced me it is useful. I know that there are some schools of thought that suggest that all form variables (client side) be named with a preceeding underscore (_fname), so that it is painfully obvious that it is not the same thing as a similarly named text (server side) variable (fname).Hope this helps someone...John Peacock------------------------------------------------------------- This message is sent to you because you are subscribed to the mailing list . To unsubscribe, E-mail to: To switch to the DIGEST mode, E-mail to Web Archive of this list is at: http://search.smithmicro.com/ John Peacock

DOWNLOAD WEBDNA NOW!

Top Articles:

Talk List

The WebDNA community talk-list is the best place to get some help: several hundred extremely proficient programmers with an excellent knowledge of WebDNA and an excellent spirit will deliver all the tips and tricks you can imagine...

Related Readings:

Any way to retrieve information from clipboard? (1998) (1997) Merging databases (1997) Calculating days, hours, minutes ago (2004) Problems with [Search] param - Mac Plugin b15 (1997) Secure Server (1997) Fwd: Protect Tag and Groups (1998) WC Host Needed (2000) Question re: FlushDatabases (1997) [group] ? (1997) RE: Last desperate attempt (1998) lineitems value? (2006) Re1000001: Setting up shop (1997) RE: formula.db, adding option prices (1997) 2 easy questions re: [showif] and [sendmail] (1997) BUG REPORT: numeric ge, le, gr & ls comparisons don't work ... (1999) Server Freeze (1998) Re2: Calculating multiple shipping... (1997) can WC render sites out? (1997) [WebDNA] [WSC] WebDNA Development Summit (2014)