On Tue, May 30, 2006 at 07:05:06PM +0900, vladas wrote:
> Sorry if this is too simple. It's still ongoing learning process for me.
> 
> I dare to ask about it on misc@ because the code will be running on OpenBSD 
> and
> because I want to  learn how to use OpenBSD properly.
> 
> Its about getenv("CONTENT_LENGTH"); usage from C. I have found two sources 
> on t
> hat, but I am not able to understand the differences and to determine which 
> code
> is better, safer.
> 
> http://www.cs.tut.fi/~jkorpela/forms/cgic.html
> 
> char *lenstr;
> char input[MAXINPUT], data[MAXINPUT];
> long len;
> printf("%s%c%c\n","Content-Type:text/html;charset=iso-8859-1",13,10);
> lenstr = getenv("CONTENT_LENGTH");
> if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len > MAXLEN)
>  printf("<P>Error in invocation - blah blah");
> else {
>  FILE *f;
>  fgets(input, len+1, stdin);
>  <.....>
> 
> http://www.coding-zone.co.uk/cpp/cgi/170401cgicpp.shtml
> 
> main()
>   {
>   char *endptr;
>   int i;
>   double contentlength;
>   char buff[10000];
>   const char *len1 = getenv("CONTENT_LENGTH");
>   contentlength=strtol(len1, &endptr, 10);
>   fread(buff, contentlength, 1, stdin);
>   }
> 
> 
> 
> To be specific:
> 
> 1. I do not get why the first example uses only
> lenstr = getenv("CONTENT_LENGTH");
> 
> while the second example goes through all of that conversion of the
> getenv("CONTENT_LENGTH") result from string to decimal number:
>   const char *len1 = getenv("CONTENT_LENGTH");
>   contentlength=strtol(len1, &endptr, 10);
>   fread(buff, contentlength, 1, stdin);

look closer (first example):
if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len > MAXLEN)

both convert the string to a number.

both examples use datatypes that i don't really like. use something like
size_t for length.

use something like strtonum/sscanf to convert a string to a number.
make sure length makes sense. -1 does not, 4,294,967,296 probably
doesn't either.

also make sure that your buffers are large enough for all possible
circumstances.


> 
> 
> 
> 2. In the CGI context, do fgets(input, len+1, stdin) and
> fread(buff, contentlength, 1, stdin) make a difference?

fgets terminates buff with a '\0', wich is imho better than plain
fread. otoh, both are ok if buff is large enough(!) and you know
what you're doing.

> 
> 
> 3. Is the code
> if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len > MAXLEN)
>  printf("<P>Error in invocation - blah blah");
> else {
>  FILE *f;
>  fgets(input, len+1, stdin);
>  <.....>
> 
> enough to prevent from the httpd buffer overflow attacks on the default
> OpenBSD httpd?

yes ;) if there is a buffer overflow, it's in your cgi, not in httpd.
httpd's chroot can prevent an attacker from getting a shell and do more
harm. Depending on your application, he can still do a lot of damage to
your application or to other clients (XSS attacks for example).

> I do understand that this question in particular is a
> broad one, but still - any comments or ideas would help as I am new to
> this.
> 
> 
> 
> Reading httpd src or manuals did not explained the differences in the logic
> of differences in those two code snippets (well at least so far).
> 
> 
> Any help would be really appreciated.

read the superb manpages of the functions you want to use. there are
often examples and pointers to things you should do/not do.

> 
> 
> 
> Vladas
> 
>

I'm sure i forgot tons of stuff :)

Tobias 

Reply via email to