Skip to content

Commit

Permalink
Merge pull request #992 from NotsoanoNimus/woadaptor_fixes
Browse files Browse the repository at this point in the history
WO Adaptor URL Sanitization Fixes
  • Loading branch information
maiksd authored Aug 25, 2022
2 parents 79721ff + 23c9775 commit b0d2d74
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 9 deletions.
40 changes: 37 additions & 3 deletions Utilities/Adaptors/Adaptor/MoreURLCUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,28 @@ WOURLError WOParseApplicationName(WOURLComponents *wc, const char *url) {
}

/*
* just validate the prefix gunk....
* just validate the prefix gunk....
* -- Added fix for invalid WO version info
*/
if (extension != NULL) {
if (version && ((extension - (version+1) < 1) || ( !isdigit((int)*(extension-1)) )))
if (version && ((extension - (version+1) < 1) || (extension - (version+1) > 5) || ( !isdigit((int)*(extension-1)) )))
return WOURLInvalidWebObjectsVersion;
} else if (version != NULL) {
if ((end - (version+1) < 1) || ( !isdigit((int)*(end-1)) ))
if ((end - (version+1) < 1) || (end - (version+1) > 5) || ( !isdigit((int)*(end-1)) ))
return WOURLInvalidWebObjectsVersion;
} else if ((end - s) > 1 )
return WOURLInvalidPrefix;

// Iterate the version string and match it to the regex: [a-z0-9\.\-_]+
// Its length is already constrained by the above conditional statements.
if ( version != NULL ) {
int versionLen = ((extension) ? extension : end)-version;
for ( const char* v = (version+1); (*v) && v < version+versionLen; v++ ) {
if ( !isalnum( (int)*v ) && (*v != '.') && (*v != '-') && (*v != '_') )
return WOURLInvalidWebObjectsVersion;
}
}

wc->prefix.start = url;
wc->prefix.length = end - url;
if (version != NULL) {
Expand Down Expand Up @@ -201,6 +212,29 @@ unsigned int SizeURL(WOURLComponents *wc) {
}


/*
* Filter for illegal URL characters in the passed adaptor request URL.
*/
WOURLError WOValidateInitialURL( const char* url ) {
const char* i;
int j;

char illegal_vals[] = { 0x0A, 0x0D };
int len = strlen( url );

i = (url != NULL) ? url : "";
WOLog(WO_DBG, "WOValidateInitialURL(): Inspecting URL: %s (%d)", url, len);

for( ; (*i) && i < (url+len); i++ ) {
for ( j = 0; j < (sizeof(illegal_vals)/sizeof(char)); j++ ) {
if ( *i == illegal_vals[j] ) return WOURLForbiddenCharacter;
}
}

return WOURLOK;
}


/*
* Dealing with URLs. Most code is provided with WebObjects and must
* be used without modification to insure forward compatibility.
Expand Down
3 changes: 3 additions & 0 deletions Utilities/Adaptors/Adaptor/MoreURLCUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ and limitations under the License.
unsigned int SizeURL(WOURLComponents *wc);
void ComposeURL(char *string, WOURLComponents *wc, int shouldProcessUrl);

// Initial URL sanitization.
WOURLError WOValidateInitialURL( const char* url );

/*
* parses just the application name from the url, returns 0 on
* success & fills in only wc.prefix, wc.webobjectsVersion and
Expand Down
3 changes: 2 additions & 1 deletion Utilities/Adaptors/Adaptor/WOURLCUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ typedef enum {
WOURLInvalidQueryString,
WOURLInvalidSuffix,
WOURLInvalidPostData,
WOURLNoPostData
WOURLNoPostData,
WOURLForbiddenCharacter
} WOURLError;

/*********** WOF dynamic URL functions. ***********/
Expand Down
7 changes: 5 additions & 2 deletions Utilities/Adaptors/Adaptor/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ typedef int intptr_t;
#define CURRENT_WOF_VERSION_MAJOR 4
#define CURRENT_WOF_VERSION_MINOR 6

#define ADAPTOR_VERSION "4.6.6"
#define ADAPTOR_VERSION "4.6.7"

/* Used to turn the value of a macro into a string literal */
#define _Str(x) #x
Expand All @@ -81,7 +81,10 @@ typedef int intptr_t;
#define WA_MAX_HOST_NAME_LENGTH 64 /* maximum length of a host name, including the null */
#define WA_MAX_INSTANCE_NUMBER_LENGTH 8 /* maximum length of an instance number, including the null */


// 2022-08-04: Uncomment this option to explicitly DISABLE URL invalid character rejections.
// Please do not change this unless you are certain about doing so!
//#define __PRESERVE_UNSAFE_URLS 1

/*
* default values for some feature settings
*/
Expand Down
12 changes: 12 additions & 0 deletions Utilities/Adaptors/Apache/mod_WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,24 @@ int WebObjects_translate(request_rec *r) {
WebObjects_config *wc;
WOURLComponents url;
WOURLError urlerr;
WOURLError charcheck;

wc = (WebObjects_config *)ap_get_module_config(r->server->module_config, &WebObjects_module);

/* WOLog(WO_DBG,"<WebObjects Apache Module> new translate: %s",r->uri); */
if (strncmp(wc->WebObjects_alias, r->uri, strlen(wc->WebObjects_alias)) == 0) {
url = WOURLComponents_Initializer;

#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( r->uri );
if ( charcheck != WOURLOK ) {
WOLog(WO_ERR, "WebObjects_translate(): declining request due to forbidden URL characters");
return DECLINED;
}
#endif


urlerr = WOParseApplicationName(&url, r->uri);
if (urlerr != WOURLOK && !((urlerr == WOURLInvalidApplicationName) && ac_authorizeAppListing(&url))) {
/* WOLog(WO_DBG,"<WebObjects Apache Module> translate - DECLINED: %s",r->uri); */
Expand Down
11 changes: 11 additions & 0 deletions Utilities/Adaptors/Apache2.2/mod_WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ int WebObjects_translate(request_rec *r) {
WebObjects_config *wc;
WOURLComponents url;
WOURLError urlerr;
WOURLError charcheck;

// get the module configuration (this is the structure created by WebObjects_create_config())
wc = ap_get_module_config(r->server->module_config, &WebObjects_module);
Expand All @@ -679,6 +680,16 @@ int WebObjects_translate(request_rec *r) {
#else
memset(&url,0,sizeof(WOURLComponents));
#endif

#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( r->uri );
if ( charcheck != WOURLOK ) {
WOLog(WO_ERR, "WebObjects_translate(): declining request due to forbidden URL characters");
return DECLINED;
}
#endif

urlerr = WOParseApplicationName(&url, r->uri);
if (urlerr != WOURLOK && !((urlerr == WOURLInvalidApplicationName) && ac_authorizeAppListing(&url))) {
WOLog(WO_DBG, "<WebObjects Apache Module> translate - DECLINED: %s", r->uri);
Expand Down
11 changes: 11 additions & 0 deletions Utilities/Adaptors/Apache2.4/mod_WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ int WebObjects_translate(request_rec *r) {
WebObjects_config *wc;
WOURLComponents url;
WOURLError urlerr;
WOURLError charcheck;

// get the module configuration (this is the structure created by WebObjects_create_config())
wc = ap_get_module_config(r->server->module_config, &WebObjects_module);
Expand All @@ -679,6 +680,16 @@ int WebObjects_translate(request_rec *r) {
#else
memset(&url,0,sizeof(WOURLComponents));
#endif

#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( r->uri );
if ( charcheck != WOURLOK ) {
WOLog(WO_ERR, "WebObjects_translate(): declining request due to forbidden URL characters");
return DECLINED;
}
#endif

urlerr = WOParseApplicationName(&url, r->uri);
if (urlerr != WOURLOK && !((urlerr == WOURLInvalidApplicationName) && ac_authorizeAppListing(&url))) {
WOLog(WO_DBG, "<WebObjects Apache Module> translate - DECLINED: %s", r->uri);
Expand Down
7 changes: 7 additions & 0 deletions Utilities/Adaptors/Apache2/mod_WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ int WebObjects_translate(request_rec *r) {
WebObjects_config *wc;
WOURLComponents url;
WOURLError urlerr;
WOURLError charcheck;

// get the module configuration (this is the structure created by WebObjects_create_config())
wc = ap_get_module_config(r->server->module_config, &WebObjects_module);
Expand All @@ -662,6 +663,12 @@ int WebObjects_translate(request_rec *r) {
if (strncmp(wc->WebObjects_alias, r->uri, strlen(wc->WebObjects_alias)) == 0) {

url = WOURLComponents_Initializer;
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( r->uri );
if ( charcheck != WOURLOK ) {
WOLog(WO_DBG, "WebObjects_translate(): declining request due to forbidden URL characters");
return DECLINED;
}
urlerr = WOParseApplicationName(&url, r->uri);
if (urlerr != WOURLOK && !((urlerr == WOURLInvalidApplicationName) && ac_authorizeAppListing(&url))) {
WOLog(WO_DBG, "<WebObjects Apache Module> translate - DECLINED: %s", r->uri);
Expand Down
14 changes: 13 additions & 1 deletion Utilities/Adaptors/CGI/WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ int doit(int argc, char *argv[], char **envp) {
const char *script_name, *path_info, *config_url, *username, *password, *config_options;
const char *reqerr;
WOURLError urlerr;
WOURLError charcheck;
strtbl *options = NULL;

#ifdef WIN32
Expand Down Expand Up @@ -314,7 +315,18 @@ int doit(int argc, char *argv[], char **envp) {
strcpy(url, script_name);
strcat(url, path_info);
WOLog(WO_INFO,"<CGI> new request: %s",url);


#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( url );
if ( charcheck != WOURLOK ) {
WOLog(WO_INFO, "Declining request due to forbidden URL characters.");
const char* _urlerr;
_urlerr = WOURLstrerror( charcheck );
die( _urlerr, HTTP_BAD_REQUEST );
}
#endif

urlerr = WOParseApplicationName(&wc, url);
if (urlerr != WOURLOK) {
const char *_urlerr;
Expand Down
16 changes: 15 additions & 1 deletion Utilities/Adaptors/FastCGI/WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ int main() {
const char *script_name, *path_info;
const char *reqerr;
WOURLError urlerr;
WOURLError charcheck;
FCGX_ParamArray hdrp_org;

exit_status = FCGX_Accept(&in, &out, &err, &hdrp );
Expand Down Expand Up @@ -329,7 +330,20 @@ int main() {
strcpy(url, script_name);
strcat(url, path_info);
WOLog(WO_INFO,"<FastCGI> new request: %s",url);


#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( url );
if ( charcheck != WOURLOK ) {
WOLog(WO_INFO, "<FastCGI> Declining request due to forbidden URL characters.");
const char* _urlerr;
_urlerr = WOURLstrerror( charcheck );
prepareAndSendErrorResponse( _urlerr, HTTP_BAD_REQUEST );
WOFREE(url);
break;
}
#endif

urlerr = WOParseApplicationName(&wc, url);
if (urlerr != WOURLOK) {
const char *_urlerr;
Expand Down
13 changes: 12 additions & 1 deletion Utilities/Adaptors/IIS/WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ __declspec(dllexport) DWORD __stdcall HttpExtensionProc(EXTENSION_CONTROL_BLOCK
char *server_protocol;
char *uri;
WOURLError urlerr;
WOURLError charcheck;

if (!adaptorEnabled)
{
Expand Down Expand Up @@ -627,8 +628,18 @@ __declspec(dllexport) DWORD __stdcall HttpExtensionProc(EXTENSION_CONTROL_BLOCK
WOLog(WO_INFO,"<WebObjects ISAPI> new request: %s", uri);
WOFREE(script_name);

urlerr = WOParseApplicationName(&wc, uri);
#ifndef __PRESERVE_UNSAFE_URLS
// Make sure the URL does not contain forbidden characters (0x0D or 0x0A).
charcheck = WOValidateInitialURL( uri );
if ( charcheck != WOURLOK ) {
WOLog(WO_INFO, "<WebObjects ISAPI> Declining request due to forbidden URL characters.");
const char* _urlerr;
_urlerr = WOURLstrerror( charcheck );
return die( p, _urlerr, HTTP_BAD_REQUEST );
}
#endif

urlerr = WOParseApplicationName(&wc, uri);
if (urlerr != WOURLOK) {
const char *_urlerr;
_urlerr = WOURLstrerror(urlerr);
Expand Down
4 changes: 4 additions & 0 deletions Utilities/Adaptors/NSAPI/WebObjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,13 @@ int WebObjectsNameTrans(pblock *pb, Session *sn, Request *rq)
/*
* make sure this is a valid WebObjects(tm) URL
*/
if (WOValidateInitialURL( uripath ) != WOURLOK )
return REQ_NOACTION;

wc = WOURLComponents_Initializer;
if (WOParseApplicationName(&wc, uripath) != WOURLOK) /* bail now if something wierd */
return REQ_NOACTION;

pblock_nvinsert(OBJECTNAME,(char *)objName,rq->vars);

approot = pblock_findval(APPROOT,pb);
Expand Down

0 comments on commit b0d2d74

Please sign in to comment.