Skip to content

Commit

Permalink
WFS-2 specific fixes for postgis time sql injections (#4834,#4815)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbonfort committed Dec 31, 2013
1 parent eb91a86 commit bb574ee
Showing 1 changed file with 32 additions and 17 deletions.
49 changes: 32 additions & 17 deletions mappostgis.c
Expand Up @@ -3345,28 +3345,33 @@ int msPostGISLayerSetTimeFilter(layerObj *lp, const char *timestring, const char
int numtimes=0,i=0,numranges=0;
size_t buffer_size = 512;
char buffer[512], bufferTmp[512];
char* escapedTimeField;

buffer[0] = '\0';
bufferTmp[0] = '\0';

if (!lp || !timestring || !timefield)
return MS_FALSE;

/* Avoid the risk of SQL injection from the timestring */
if( strchr(timestring,'\'') || strchr(timestring, '\\') ) {
msSetError(MS_MISCERR, "Invalid time filter.", "msPostGISLayerSetTimeFilter()");
return MS_FALSE;
msSetError(MS_MISCERR, "Invalid time filter.", "msPostGISLayerSetTimeFilter()");
return MS_FALSE;
}
escapedTimeField = msLayerEscapePropertyName(lp, timefield);

/* discrete time */
if (strstr(timestring, ",") == NULL &&
strstr(timestring, "/") == NULL) { /* discrete time */
createPostgresTimeCompareSimple(timefield, timestring, buffer, buffer_size);
createPostgresTimeCompareSimple(escapedTimeField, timestring, buffer, buffer_size);
} else {

/* multiple times, or ranges */
atimes = msStringSplit (timestring, ',', &numtimes);
if (atimes == NULL || numtimes < 1)
if (atimes == NULL || numtimes < 1) {
msFree(escapedTimeField);
return MS_FALSE;
}

strlcat(buffer, "(", buffer_size);
for(i=0; i<numtimes; i++) {
Expand All @@ -3375,16 +3380,23 @@ int msPostGISLayerSetTimeFilter(layerObj *lp, const char *timestring, const char
}
strlcat(buffer, "(", buffer_size);
aranges = msStringSplit(atimes[i], '/', &numranges);
if(!aranges) return MS_FALSE;
if(!aranges) {
msFree(escapedTimeField);
msFreeCharArray(atimes, numtimes);
return MS_FALSE;
}
if(numranges == 1) {
/* we don't have range, just a simple time */
createPostgresTimeCompareSimple(timefield, atimes[i], bufferTmp, buffer_size);
createPostgresTimeCompareSimple(escapedTimeField, atimes[i], bufferTmp, buffer_size);
strlcat(buffer, bufferTmp, buffer_size);
} else if(numranges == 2) {
/* we have a range */
createPostgresTimeCompareRange(timefield, aranges[0], aranges[1], bufferTmp, buffer_size);
createPostgresTimeCompareRange(escapedTimeField, aranges[0], aranges[1], bufferTmp, buffer_size);
strlcat(buffer, bufferTmp, buffer_size);
} else {
msFree(escapedTimeField);
msFreeCharArray(aranges, numranges);
msFreeCharArray(atimes, numtimes);
return MS_FALSE;
}
msFreeCharArray(aranges, numranges);
Expand All @@ -3393,21 +3405,24 @@ int msPostGISLayerSetTimeFilter(layerObj *lp, const char *timestring, const char
strlcat(buffer, ")", buffer_size);
msFreeCharArray(atimes, numtimes);
}

msFree(escapedTimeField);

if(!*buffer) {
return MS_FALSE;
}

if(lp->filteritem) free(lp->filteritem);
lp->filteritem = msStrdup(timefield);
if (&lp->filter) {
/* if the filter is set and it's a string type, concatenate it with
the time. If not just free it */
if (lp->filter.type == MS_EXPRESSION) {
snprintf(bufferTmp, buffer_size, "(%s) and %s", lp->filter.string, buffer);
loadExpressionString(&lp->filter, bufferTmp);
} else {
freeExpression(&lp->filter);
loadExpressionString(&lp->filter, buffer);
}

/* if the filter is set and it's a string type, concatenate it with
the time. If not just free it */
if (lp->filter.type == MS_EXPRESSION) {
snprintf(bufferTmp, buffer_size, "(%s) and %s", lp->filter.string, buffer);
loadExpressionString(&lp->filter, bufferTmp);
} else {
freeExpression(&lp->filter);
loadExpressionString(&lp->filter, buffer);
}


Expand Down

0 comments on commit bb574ee

Please sign in to comment.