⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ratproxy.c

📁 Google 推出一套免費的 Web 安全評估工具
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (!strcasecmp(BEST_MIME,"text/html") || rp_strcasestr(BEST_MIME,"script") ||        !strcasecmp(BEST_MIME,"application/json") ||        !strcasecmp(BEST_MIME,"text/css") || !strcasecmp(BEST_MIME,"application/xhtml+xml"))      SHOW_MSG(2,"Potential mixed content",0,m);      else SHOW_MSG(0,"Potential mixed content",0,m);  }  /* If instructed to do so, adjust XSRF "safety" rating based on packet     replay now. */  if (try_attacks) try_replay_xsrf(req,res);  /***********************   * HEADER BASED CHECKS *   ***********************/  if (res->code < 200 || res->code >= 400) {    switch (NOECHO(m = get_modifiers(req,res))) {      /* No big deal, but warrants an investigation; more important if         the content is user-specific. */      case 0:      case MOD_PRED:        SHOW_MSG(0,"HTTP errors",0,m); break;      case MOD_AUTH:      case MOD_PRED | MOD_AUTH:        SHOW_MSG(1,"HTTP errors",0,m); break;     }  }  /* Detect 302 with Location: that contains req->query or req->payload,     and lacks XSRF token? */  if (res->location && (req->query || req->payload) && !req->xsrf_safe) {     _u8* hname = strdup(res->location), *y;     if (!hname) fatal("out of memory");     if (!strncasecmp(hname,"http://",7)) hname += 7; else     if (!strncasecmp(hname,"https://",8)) hname += 8;     y = hname;     while (isalnum(*y) || *y == '-' || *y == '.') y++;     *y = 0;     if (hname[0] && ((req->query   && rp_strcasestr(req->query,hname)) ||                      (req->payload && rp_strcasestr(req->payload,hname)))) {       SHOW_MSG(3,"HTTP redirector",0,1);     }  }  /* If not a HTTP redirector, examine for HTML redirection anyway */  if (!res->location && (req->query || req->payload) && res->payload && !req->xsrf_safe) {    _u8* mref=rp_strcasestr(res->payload,"HTTP-EQUIV=\"Refresh\"");    _u8* hname = mref ? rp_strcasestr(mref + 20, ";URL=") : 0;    if (hname) {       _u8* mrefend = strchr(mref + 20,'>'), *y;       if (mrefend && hname < mrefend) {         hname = strdup(hname + 5);         if (!hname) fatal("out of memory");         if (!strncasecmp(hname,"http://",7)) hname += 7; else         if (!strncasecmp(hname,"https://",8)) hname += 8;         y = hname;         while (isalnum(*y) || *y == '-' || *y == '.') y++;         *y = 0;         if (hname[0] && ((req->query   && rp_strcasestr(req->query,hname)) ||                          (req->payload && rp_strcasestr(req->payload,hname)))) {           SHOW_MSG(3,"HTML META redirector",0,1);         }        }     }  }  if (req->multipart) {    m = get_modifiers(req,res);    SHOW_MSG(0,"File upload forms",0,m);   }  if (all_post && req->payload && strcasecmp(req->method,"GET")) {    m = get_modifiers(req,res);    SHOW_MSG(0,"All POST requests",0,m);  }  if (unique_cookies(&req->cookies,&res->cookies) && !req->xsrf_safe && (req->payload || req->query)) {    m = get_modifiers(req,res);    SHOW_MSG(2,"Cookie issuer with no XSRF protection",0,m);    /* TODO: Maybe check if query data copied over to cookies. */  }  if (all_cookie && unique_cookies(&req->cookies,&res->cookies)) {    m = get_modifiers(req,res);    SHOW_MSG(0,"All cookie setting URLs",0,m);  }  /* If there's a request that requires authentication and accept parameters,     it should probably employ anti-XSRF protection of some sort. */  if (!req->xsrf_safe && (req->payload || req->query)) {    m = get_modifiers(req,res);    if (m & MOD_AUTH) {      if (!strcasecmp(req->method,"GET")) {        if (get_xsrf)          SHOW_MSG(0,"GET query with no XSRF protection",0,m);      } else        SHOW_MSG(3,"POST query with no XSRF protection",0,m);    } else {      /* POST requests that do not require authentication are interesting,         though not necessarily very troubling. */      if (strcasecmp(req->method,"GET"))        SHOW_MSG(1,"POST query with no XSRF protection",0,m);    }  }  if (res->has_multiple) {    /* Duplicate Content-Type or Content-Disposition headers are a sure       way to get into trouble. */    switch (NOECHO(m = get_modifiers(req,res))) {         case 0:        SHOW_MSG(1,"Ambiguous HTTP content headers",0,m); break;      case MOD_PRED:      case MOD_AUTH:        SHOW_MSG(2,"Ambiguous HTTP content headers",0,m); break;      case MOD_PRED | MOD_AUTH:        SHOW_MSG(3,"Ambiguous HTTP content headers",0,m); break;      }  }  /* Unusual, but hey, let's report it because we can. */  if (res->has_badclen)    SHOW_MSG(3,"Misstated Content-Length",0,0);  /* POST requests that pass auth tokens between domains. If coming     from an excluded domain, this is more important. */  if (req->ref_host && strcmp(req->method,"GET") &&      strcasecmp(req->host,req->ref_host)) {    if (!host_ok(req->ref_host))       SHOW_REF_MSG(2,"Cross-domain POST requests",0);    else      SHOW_REF_MSG(1,"Cross-domain POST requests",0);  }  /* Report caching headers issues (but only once!) */  if (!req->from_ssl && unique_cookies(&req->cookies,&res->cookies) && is_public(req,res)) {    switch (NOECHO(m = get_modifiers(req,res))) {      case 0:      case MOD_AUTH:        SHOW_MSG(1,"Bad caching headers","cacheable SetCookie",m);        break;      case MOD_PRED:      case MOD_AUTH | MOD_PRED:        SHOW_MSG(3,"Bad caching headers","cacheable SetCookie",m);        break;    }  } else if (!req->from_ssl && is_public(req,res) == 2 && res->payload_len && res->code < 300) {    m = get_modifiers(req,res);    if (NOECHO(m) == (MOD_AUTH | MOD_PRED)) SHOW_MSG(3,"Bad caching headers","Expires/Date/Cache-Control mismatch",m);      else if (NOECHO(m) == MOD_AUTH) SHOW_MSG(2,"Bad caching headers","Expires/Date/Cache-Control mismatch",m);  }  /************************   * PAYLOAD BASED CHECKS *   ************************/  /* If the document is empty, bail out (everything below relies on non-NULL res->payload). */  if (!res->payload_len) goto skip_tests;  if (res->is_text && (!res->charset || res->bad_cset)) {    /* Missing charsets and typos lead to UTF-7 cross-site scripting. */    if (strcasecmp(BEST_MIME,"text/css")) {      /* Cases where content is echoed back are higher risk, but we care         about stored attacks too. */      switch (NOECHO(m = get_modifiers(req,res))) {           case 0:          SHOW_MSG(ECHO(m) ? 3 : 1,"Bad or no charset declared for renderable file",0,m); break;        case MOD_PRED:        case MOD_AUTH:          SHOW_MSG(ECHO(m) ? 3 : 1,"Bad or no charset declared for renderable file",0,m); break;        case MOD_PRED | MOD_AUTH:          SHOW_MSG(ECHO(m) ? 3 : 2,"Bad or no charset declared for renderable file",0,m); break;        }    }  }  if (res->mime_type && !strcasecmp(res->mime_type,"text/plain")) {    /* Modern interactive websites have very few reasons to serve        text/plain documents, and if these documents are user-controlled,       content sniffing can lead to XSS. */    /* Let's just ignore text/css; the next check will catch it anyway,       and it's nearly guaranteed to be harmless. */    if (strcasecmp(BEST_MIME,"text/css"))       switch (NOECHO(m = get_modifiers(req,res))) {      case 0:        SHOW_MSG(1,"MIME type set to text/plain",0,m); break;      case MOD_AUTH:      case MOD_PRED:        SHOW_MSG(ECHO(m) ? 2 : 1,"MIME type set to text/plain",0,m); break;      case MOD_PRED | MOD_AUTH:        SHOW_MSG(ECHO(m) ? 3 : 2,"MIME type set to text/plain",0,m); break;     }  }  if (!res->mime_type) {    /* Having no MIME type almost always warrants scrutiny, as content       sniffing runs rampant and may have a browser-specific outcome. */    switch (NOECHO(m = get_modifiers(req,res))) {      case 0:        SHOW_MSG(1,"MIME type missing",0,m); break;      case MOD_PRED:      case MOD_AUTH:        SHOW_MSG(ECHO(m) ? 2 : 1,"MIME type missing",0,m); break;      case MOD_PRED | MOD_AUTH:        SHOW_MSG(ECHO(m) ? 3 : 2,"MIME type missing",0,m); break;     }  }  /* Let's be annoying here for initial betas, why not?. */  if (res->payload_len > 10 && res->mime_type && !res->sniffed_mime)    debug(">>> Failed to detect MIME type '%s' (%s:%u/%s?%s), tell lcamtuf@google.com <<<\n",      S(res->mime_type,0), S(req->host,0), req->port, S(req->path,0), req->query ?       S(req->query,0) : (_u8*)"");  if (res->sniffed_mime && res->mime_type &&      strcasecmp(res->mime_type, res->sniffed_mime)) {    if (res->is_text) {      /* MIME mismatch on text formats that are rendered by the browser         is usually a major problem and may lead to XSS. */      /* Do not be too picky about HTML - XHTML mismatches, though... */      if (res->mime_type && res->sniffed_mime &&          !strcasecmp(res->mime_type,"text/html") &&          !strcasecmp(res->sniffed_mime,"application/xhtml+xml"))        goto ignore_mime_mismatch;      if (strcasecmp(BEST_MIME,"text/css"))         switch (NOECHO(m = get_modifiers(req,res))) {          case 0:          SHOW_MSG(1,"MIME type mismatch on renderable file",0,m);           break;        case MOD_AUTH:        case MOD_PRED:          SHOW_MSG(ECHO(m) ? 2 : 1,"MIME type mismatch on renderable file",0,m); break;        case MOD_PRED | MOD_AUTH:          SHOW_MSG(ECHO(m) ? 3 : 2,"MIME type mismatch on renderable file",0,m); break;         }    } else if (!strncasecmp(BEST_MIME,"image/",6)) {      /* Subtle mismatches with images may have disastrous effects as          content sniffing inevitably kicks in and may lead to HTML         parsing in EXIF or comment data.*/      switch (NOECHO(m = get_modifiers(req,res))) {          case 0:          SHOW_MSG(1,"MIME type mismatch on image file",0,m); break;        case MOD_AUTH:        case MOD_PRED:          SHOW_MSG(2,"MIME type mismatch on image file",0,m); break;        case MOD_PRED | MOD_AUTH:          SHOW_MSG(3,"MIME type mismatch on image file",0,m); break;         }    } else {      if (!strcasecmp(res->mime_type,"application/octet-stream")) {        /* Defaulting to application/octet-stream may trigger content           sniffing. */        switch (NOECHO(m = get_modifiers(req,res))) {             case 0:            SHOW_MSG(1,"Generic MIME type used",0,m); break;          case MOD_AUTH:          case MOD_PRED:            SHOW_MSG(ECHO(m) ? 2 : 1,"Generic MIME type used",0,m); break;          case MOD_PRED | MOD_AUTH:            SHOW_MSG(ECHO(m) ? 3 : 2,"Generic MIME type used",0,m); break;           }      } else {        /* Other MIME type mismatches still warrant attention, as this           might be a result of a typo or the like. */        switch (NOECHO(m = get_modifiers(req,res))) {             case 0:          case MOD_AUTH:          case MOD_PRED:            SHOW_MSG(1,"MIME type mismatch on binary file",0,m); break;          case MOD_PRED | MOD_AUTH:            SHOW_MSG(2,"MIME type mismatch on binary file",0,m); break;           }      }    }  }ignore_mime_mismatch:  if ((rp_strcasestr(BEST_MIME,"script") || !strcasecmp(BEST_MIME,"application/json"))) {    /* JSON is almost always worth inspecting - doubly so if not secured against XSRF. */    switch (NOECHO(m = get_modifiers(req,res))) {         case 0:      case MOD_PRED:        break;      case MOD_AUTH:        SHOW_MSG(standalone_script(res->payload) ? 0 : 1,                 "Dynamic Javascript for direct inclusion",0,m); break;      case MOD_PRED | MOD_AUTH:        /* TODO: Move this to a proper Javascript analyzer instead. */        if (standalone_script(res->payload)) {          SHOW_MSG(0,"Dynamic Javascript for direct inclusion",0,m);        } else if (is_json_safe(res->payload)) {          SHOW_MSG(ECHO(m) ? 1 : 0,"Dynamic Javascript for direct inclusion",0,m);        } else {          SHOW_MSG(ECHO(m) ? 3 : 2,"Dynamic Javascript for direct inclusion",0,m);        }        break;     }  }  if (!strcasecmp(BEST_MIME,"image/png") && !res->is_attach) {    switch (NOECHO(m = get_modifiers(req,res))) {         case 0:      case MOD_PRED:        if (check_png) SHOW_MSG(2,"Inline PNG image",0,m); break;      case MOD_AUTH:        SHOW_MSG(2,"Inline PNG image",0,m); break;      case MOD_PRED | MOD_AUTH:        SHOW_MSG(3,"Inline PNG image",0,m); break;      }  }  /* Echoed markup in a query is bad. */  for (i=0;i<req->p.c;i++)    if (!req->p.fn[i][0] && strchr(req->p.v2[i],'<') && strstr(res->payload,req->p.v2[i])) {       switch (NOECHO(m = get_modifiers(req,res))) {           case 0:        case MOD_AUTH:          SHOW_MSG(2,"Direct markup echoed back",req->p.v2[i],m); break;        case MOD_PRED:        case MOD_PRED | MOD_AUTH:          SHOW_MSG(3,"Direct markup echoed back",req->p.v2[i],m); break;       }      break;    }  /* Non-echoed paths in query are often bad, though there are some common patterns     of false psoitives. */  for (i=0;i<req->p.c;i++) if (!req->p.fn[i][0] && strlen(req->p.v2[i]) < MAX_FPATH &&    strcmp(req->p.v1[i],"utmp") /* Analytics-specific. */ ) {    _u8* x = strchr(req->p.v2[i],'/');    _u8* y = strchr(req->p.v2[i],'.');    if (!x) continue;				/* No slash - no problem       */    if (y && y <= x) continue;			/* "www.foo.com/bar/baz.jpg"   */    if (x[1] == '/') continue;			/* "http://www.foo.com/"       */    if (isdigit(x[1]) && isdigit(x[2]) && x[3] == '/') continue; /* 01/02/2007 */    if (isdigit(x[1]) && isdigit(x[3]) && x[2] == '/') continue; /* 01/2/2007 */    do { x++; } while (isalnum(*x) || *x == '_');

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -