Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Query and post parameters may never begin with an upper-case letter. To allow that is a huge security hole. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | noJsonCgiFlag |
| Files: | files | file ages | folders |
| SHA3-256: |
72c721eacf9401f3e6e84be1994debfe |
| User & Date: | drh 2019-08-27 10:40:46.490 |
Context
|
2019-08-27
| ||
| 12:51 | Change 'NO_JSON' to lowercase. Remove other branch changes that are now superfluous. ... (check-in: 8baac2646c user: mistachkin tags: noJsonCgiFlag) | |
| 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) | |
| 07:21 | Restore legacy title handling behavior for TH1 docs (changed via check-in [8abeb62737c2b527]). ... (check-in: 4219002631 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) | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
560 561 562 563 564 565 566 |
** 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);
}
| < < < < < < < < < < < < < < < | 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
** special character and therefore does not decode it.
|
| ︙ | ︙ | |||
627 628 629 630 631 632 633 |
z++;
}
dehttpize(zValue);
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
| | | 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
z++;
}
dehttpize(zValue);
}else{
if( *z ){ *z++ = 0; }
zValue = "";
}
if( fossil_islower(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 */
}
}
|
| ︙ | ︙ | |||
771 772 773 774 775 776 777 |
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);
| | | | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 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 |
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 && fossil_islower(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 && fossil_islower(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 && fossil_islower(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( fossil_islower(zName[0]) ){
cgi_replace_query_parameter(zName, zValue);
}
}
return 0;
}
/*
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
209 210 211 212 213 214 215 |
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 */
| < | 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(). */
|
| ︙ | ︙ | |||
729 730 731 732 733 734 735 |
"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;
| < | 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;
|
| ︙ | ︙ | |||
2012 2013 2014 2015 2016 2017 2018 |
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;
| < < < < < < < < | 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 |
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.
*/
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
1196 1197 1198 1199 1200 1201 1202 |
@ g.zBaseURL = %h(g.zBaseURL)<br />
@ g.zHttpsURL = %h(g.zHttpsURL)<br />
@ g.zTop = %h(g.zTop)<br />
@ g.zPath = %h(g.zPath)<br />
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ g.isHuman = %d(g.isHuman)<br />
| < | 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 |
@ g.zBaseURL = %h(g.zBaseURL)<br />
@ g.zHttpsURL = %h(g.zHttpsURL)<br />
@ g.zTop = %h(g.zTop)<br />
@ g.zPath = %h(g.zPath)<br />
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ g.isHuman = %d(g.isHuman)<br />
if( g.nRequest ){
@ g.nRequest = %d(g.nRequest)<br />
}
if( g.nPendingRequest>1 ){
@ g.nPendingRequest = %d(g.nPendingRequest)<br />
}
@ capabilities = %s(find_capabilities(zCap))<br />
|
| ︙ | ︙ |