Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | If the '--cgiupperparamsok' command line option or 'uppercase_params' CGI control line are present, allow parameter names to start with an uppercase letter. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | noJsonCgiFlag |
| Files: | files | file ages | folders |
| SHA3-256: |
ab0d81f893b1f60c13cc11be0169685f |
| User & Date: | mistachkin 2019-08-27 05:34:42.515 |
Context
|
2019-08-27
| ||
| 10:40 | Query and post parameters may never begin with an upper-case letter. To allow that is a huge security hole. ... (check-in: 72c721eacf user: drh tags: noJsonCgiFlag) | |
| 05:55 | More refinements. ... (check-in: c1f4a84694 user: mistachkin tags: noJsonCgiFlag) | |
| 05:34 | If the '--cgiupperparamsok' command line option or 'uppercase_params' CGI control line are present, allow parameter names to start with an uppercase letter. ... (check-in: ab0d81f893 user: mistachkin tags: noJsonCgiFlag) | |
| 04:15 | Make it possible to disable JSON auto-detection in the CGI subsystem. ... (check-in: a775435357 user: mistachkin tags: noJsonCgiFlag) | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
560 561 562 563 564 565 566 567 568 569 570 571 572 573 |
** Add a query parameter. The zName portion is fixed but a copy
** must be made of zValue.
*/
void cgi_setenv(const char *zName, const char *zValue){
cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
}
/*
** Add a list of query parameters or cookies to the parameter set.
**
** Each parameter is of the form NAME=VALUE. Both the NAME and the
** VALUE may be url-encoded ("+" for space, "%HH" for other special
** characters). But this routine assumes that NAME contains no
| > > > > > > > > > > > > > | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
** Add a query parameter. The zName portion is fixed but a copy
** must be made of zValue.
*/
void cgi_setenv(const char *zName, const char *zValue){
cgi_set_parameter_nocopy(zName, mprintf("%s",zValue), 0);
}
/*
** Returns non-zero if the specified character is lower case -OR-
** CGI has been configured to allow uppercase parameter names.
*/
int cgi_char_allowed(char c){
if( fossil_islower(c) ){
return 1; /* lowercase letter, always OK */
}else if( fossil_isupper(c) && g.cgiUpperParamsOk ){
return 1; /* uppercase letter, OK if allowed explicitly */
}
return 0; /* something else, never OK */
}
/*
** Add a list of query parameters or cookies to the parameter set.
**
** Each parameter is of the form NAME=VALUE. Both the NAME and the
** VALUE may be url-encoded ("+" for space, "%HH" for other special
** characters). But this routine assumes that NAME contains no
|
| ︙ | ︙ | |||
613 614 615 616 617 618 619 |
z++;
}
dehttpize(zValue);
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
| | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
z++;
}
dehttpize(zValue);
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
if( cgi_char_allowed(zName[0]) && fossil_no_strange_characters(zName+1) ){
cgi_set_parameter_nocopy(zName, zValue, isQP);
}
#ifdef FOSSIL_ENABLE_JSON
json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
#endif /* FOSSIL_ENABLE_JSON */
}
}
|
| ︙ | ︙ | |||
757 758 759 760 761 762 763 |
zBoundry = get_line_from_string(&z, &len);
if( zBoundry==0 ) return;
while( (zLine = get_line_from_string(&z, &len))!=0 ){
if( zLine[0]==0 ){
int nContent = 0;
zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
| | | | | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 |
zBoundry = get_line_from_string(&z, &len);
if( zBoundry==0 ) return;
while( (zLine = get_line_from_string(&z, &len))!=0 ){
if( zLine[0]==0 ){
int nContent = 0;
zValue = get_bounded_content(&z, &len, zBoundry, &nContent);
if( zName && zValue && cgi_char_allowed(zName[0]) ){
cgi_set_parameter_nocopy(zName, zValue, 1);
if( showBytes ){
cgi_set_parameter_nocopy(mprintf("%s:bytes", zName),
mprintf("%d",nContent), 1);
}
}
zName = 0;
showBytes = 0;
}else{
nArg = tokenize_line(zLine, count(azArg), azArg);
for(i=0; i<nArg; i++){
int c = fossil_tolower(azArg[i][0]);
int n = strlen(azArg[i]);
if( c=='c' && sqlite3_strnicmp(azArg[i],"content-disposition:",n)==0 ){
i++;
}else if( c=='n' && sqlite3_strnicmp(azArg[i],"name=",n)==0 ){
zName = azArg[++i];
}else if( c=='f' && sqlite3_strnicmp(azArg[i],"filename=",n)==0 ){
char *z = azArg[++i];
if( zName && z && cgi_char_allowed(zName[0]) ){
cgi_set_parameter_nocopy(mprintf("%s:filename",zName), z, 1);
}
showBytes = 1;
}else if( c=='c' && sqlite3_strnicmp(azArg[i],"content-type:",n)==0 ){
char *z = azArg[++i];
if( zName && z && cgi_char_allowed(zName[0]) ){
cgi_set_parameter_nocopy(mprintf("%s:mimetype",zName), z, 1);
}
}
}
}
}
}
|
| ︙ | ︙ |
Changes to src/dispatch.c.
| ︙ | ︙ | |||
192 193 194 195 196 197 198 |
*(z++) = 0;
cgi_delete_query_parameter(zName);
zName = "";
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
| | | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
*(z++) = 0;
cgi_delete_query_parameter(zName);
zName = "";
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
if( cgi_char_allowed(zName[0]) ){
cgi_replace_query_parameter(zName, zValue);
}
}
return 0;
}
/*
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
char isHTTP; /* True if server/CGI modes, else assume CLI. */
char javascriptHyperlink; /* If true, set href= using script, not HTML */
Blob httpHeader; /* Complete text of the HTTP request header */
UrlData url; /* Information about current URL */
const char *zLogin; /* Login name. NULL or "" if not logged in. */
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
** SSL client identity */
int useLocalauth; /* No login required if from 127.0.0.1 */
int noPswd; /* Logged in without password (on 127.0.0.1) */
int userUid; /* Integer user id */
int isHuman; /* True if access by a human, not a spider or bot */
int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
** accessed through get_comment_format(). */
| > | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
char isHTTP; /* True if server/CGI modes, else assume CLI. */
char javascriptHyperlink; /* If true, set href= using script, not HTML */
Blob httpHeader; /* Complete text of the HTTP request header */
UrlData url; /* Information about current URL */
const char *zLogin; /* Login name. NULL or "" if not logged in. */
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of
** SSL client identity */
int cgiUpperParamsOk; /* Allow CGI parameters to start with uppercase */
int useLocalauth; /* No login required if from 127.0.0.1 */
int noPswd; /* Logged in without password (on 127.0.0.1) */
int userUid; /* Integer user id */
int isHuman; /* True if access by a human, not a spider or bot */
int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be
** accessed through get_comment_format(). */
|
| ︙ | ︙ | |||
728 729 730 731 732 733 734 735 736 737 738 739 740 741 |
"another flag and is treated as such. --args FILENAME may be used\n"
"in conjunction with any other flags.\n");
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.rcvid = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fCgiTrace = find_option("cgitrace", 0, 0)!=0;
g.fSshClient = 0;
| > | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
"another flag and is treated as such. --args FILENAME may be used\n"
"in conjunction with any other flags.\n");
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.rcvid = 0;
g.cgiUpperParamsOk = find_option("cgiupperparamsok", 0, 0)!=0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
g.fCgiTrace = find_option("cgitrace", 0, 0)!=0;
g.fSshClient = 0;
|
| ︙ | ︙ | |||
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 |
fossil_binary_mode(g.httpIn);
g.cgiOutput = 1;
fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT);
blob_read_from_file(&config, zFile, ExtFILE);
while( blob_line(&config, &line) ){
if( !blob_token(&line, &key) ) continue;
if( blob_buffer(&key)[0]=='#' ) continue;
if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
/* repository: FILENAME
**
** The name of the Fossil repository to be served via CGI. Most
** fossil CGI scripts have a single non-comment line that contains
** this one entry.
*/
| > > > > > > > > | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 |
fossil_binary_mode(g.httpIn);
g.cgiOutput = 1;
fossil_set_timeout(FOSSIL_DEFAULT_TIMEOUT);
blob_read_from_file(&config, zFile, ExtFILE);
while( blob_line(&config, &line) ){
if( !blob_token(&line, &key) ) continue;
if( blob_buffer(&key)[0]=='#' ) continue;
if( blob_eq(&key, "uppercase_params") ){
/* uppercase_params
**
** Allow CGI parameters to start with an uppercase letter.
*/
g.cgiUpperParamsOk = 1;
continue;
}
if( blob_eq(&key, "repository:") && blob_tail(&line, &value) ){
/* repository: FILENAME
**
** The name of the Fossil repository to be served via CGI. Most
** fossil CGI scripts have a single non-comment line that contains
** this one entry.
*/
|
| ︙ | ︙ |