diff --git a/source/jst_internal.c b/source/jst_internal.c index e7312f0..4d55f94 100644 --- a/source/jst_internal.c +++ b/source/jst_internal.c @@ -164,6 +164,7 @@ int read_file(const char *filename, char** bufout, size_t* lenout) { FILE* pf; size_t size; + long tell_result; size_t rc; char* buf; @@ -179,8 +180,31 @@ int read_file(const char *filename, char** bufout, size_t* lenout) return 0; } - fseek(pf, 0, SEEK_END); - size = ftell(pf); + if (fseek(pf, 0, SEEK_END) != 0) + { + CosaPhpExtLog("read_file fseek failed:%s error:%s\n", filename, strerror(errno)); + fclose(pf); + fprintf(stderr, "Error: fseek failed %s\n", filename); + return 0; + } + + errno = 0; + tell_result = ftell(pf); + if (tell_result < 0) + { + CosaPhpExtLog("read_file ftell failed:%s error:%s\n", filename, strerror(errno)); + fclose(pf); + fprintf(stderr, "Error: ftell failed %s\n", filename); + return 0; + } + if ((unsigned long long)tell_result > (unsigned long long)(SIZE_MAX - 1)) + { + CosaPhpExtLog("read_file size overflow:%s size:%ld\n", filename, tell_result); + fclose(pf); + fprintf(stderr, "Error: file too large %s\n", filename); + return 0; + } + size = (size_t)tell_result; rewind(pf); buf = (char*)calloc(size+1, 1); diff --git a/source/jst_session.c b/source/jst_session.c index 69f542f..5d0d334 100644 --- a/source/jst_session.c +++ b/source/jst_session.c @@ -75,6 +75,9 @@ static duk_ret_t session_start(duk_context *ctx) { CosaPhpExtLog("%s: entered\n", __PRETTY_FUNCTION__); const char* cookie; + const char* sesid_end; + size_t sesid_len; + char parsed_sesid[SESSION_ID_LENGTH + 1]; /* if session already created then do nothing */ if(session_identifier) { @@ -112,14 +115,20 @@ static duk_ret_t session_start(duk_context *ctx) if(sesid) { sesid += 7; - int len = strlen(sesid); - if(len >= SESSION_ID_LENGTH) + sesid_end = strchr(sesid, ';'); + sesid_len = sesid_end ? (size_t)(sesid_end - sesid) : strlen(sesid); + if(sesid_len == SESSION_ID_LENGTH) { int idx = SESSION_PREFIX_LEN; int isvalid = 1; + if(strncmp(sesid, SESSION_PREFIX, SESSION_PREFIX_LEN) != 0) + { + CosaPhpExtLog("Invalid SessionID prefix\n"); + isvalid = 0; + } /* Validate session ID*/ - while ( idx < SESSION_ID_LENGTH) { - if (!isalnum(sesid[idx])) { + while (isvalid && idx < SESSION_ID_LENGTH) { + if (!isalnum((unsigned char)sesid[idx])) { CosaPhpExtLog("Invalid SessionID\n"); isvalid = 0; break; @@ -128,19 +137,20 @@ static duk_ret_t session_start(duk_context *ctx) } if(isvalid) { - sesid = strtok(sesid, ";"); - const char filename[SESSION_FILE_MAX_PATH]; - snprintf(filename, SESSION_FILE_MAX_PATH, "%s/%s", SESSION_TMP_DIR, sesid); + memcpy(parsed_sesid, sesid, SESSION_ID_LENGTH); + parsed_sesid[SESSION_ID_LENGTH] = '\0'; + char filename[SESSION_FILE_MAX_PATH]; + snprintf(filename, SESSION_FILE_MAX_PATH, "%s/%s", SESSION_TMP_DIR, parsed_sesid); CosaPhpExtLog("%s: Checking for Session file %s\n", __PRETTY_FUNCTION__, filename); if (access(filename, F_OK) == 0) { CosaPhpExtLog("%s: Session file %s exists\n", __PRETTY_FUNCTION__, filename); - strncpy(session_identifier, sesid, SESSION_ID_LENGTH); + strncpy(session_identifier, parsed_sesid, SESSION_ID_LENGTH); } else { CosaPhpExtLog("%s: Failed to read Session file %s\n", __PRETTY_FUNCTION__, filename); } } - } else { + } else { CosaPhpExtLog("Invalid SessionID Entropy\n"); } }