mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 05:45:59 +03:00
Added new directive (SecPdfProtectMethod) to enable the user to choose between
using token redirection (falling back on forced download in some cases) and forced download (in all cases).
This commit is contained in:
parent
8b843127ba
commit
74738b29b0
@ -14,7 +14,7 @@
|
||||
|
||||
#include "modsecurity.h"
|
||||
#include "msc_logging.h"
|
||||
|
||||
#include "pdf_protect.h"
|
||||
#include "http_log.h"
|
||||
|
||||
/* #define DEBUG_CONF 1 */
|
||||
@ -90,6 +90,7 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
|
||||
dcfg->pdfp_timeout = NOT_SET;
|
||||
dcfg->pdfp_token_name = NOT_SET_P;
|
||||
dcfg->pdfp_only_get = NOT_SET;
|
||||
dcfg->pdfp_method = NOT_SET;
|
||||
|
||||
/* Geo Lookups */
|
||||
dcfg->geo = NOT_SET_P;
|
||||
@ -384,6 +385,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
|
||||
? parent->pdfp_token_name : child->pdfp_token_name);
|
||||
merged->pdfp_only_get = (child->pdfp_only_get == NOT_SET
|
||||
? parent->pdfp_only_get : child->pdfp_only_get);
|
||||
merged->pdfp_method = (child->pdfp_method == NOT_SET
|
||||
? parent->pdfp_method : child->pdfp_method);
|
||||
|
||||
/* Geo Lookup */
|
||||
merged->geo = (child->geo == NOT_SET_P
|
||||
@ -457,6 +460,7 @@ void init_directory_config(directory_config *dcfg) {
|
||||
if (dcfg->pdfp_timeout == NOT_SET) dcfg->pdfp_timeout = 10;
|
||||
if (dcfg->pdfp_token_name == NOT_SET_P) dcfg->pdfp_token_name = "PDFPTOKEN";
|
||||
if (dcfg->pdfp_only_get == NOT_SET) dcfg->pdfp_only_get = 1;
|
||||
if (dcfg->pdfp_method == NOT_SET) dcfg->pdfp_method = PDF_PROTECT_METHOD_TOKEN_REDIRECTION;
|
||||
|
||||
/* Geo Lookup */
|
||||
if (dcfg->geo == NOT_SET_P) dcfg->geo = NULL;
|
||||
@ -1195,6 +1199,25 @@ static const char *cmd_pdf_protect_intercept_get_only(cmd_parms *cmd, void *_dcf
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_pdf_protect_method(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if (strcasecmp(p1, "TokenRedirection") == 0) {
|
||||
dcfg->pdfp_method = PDF_PROTECT_METHOD_TOKEN_REDIRECTION;
|
||||
} else
|
||||
if (strcasecmp(p1, "ForcedDownload") == 0) {
|
||||
dcfg->pdfp_method = PDF_PROTECT_METHOD_FORCED_DOWNLOAD;
|
||||
} else {
|
||||
return (const char *)apr_psprintf(cmd->pool,
|
||||
"ModSecurity: Unrecognised parameter value for SecPdfProtectMethod: %s", p1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* -- Geo Lookup configuration -- */
|
||||
|
||||
static const char *cmd_geo_lookups_db(cmd_parms *cmd, void *_dcfg,
|
||||
@ -1550,6 +1573,14 @@ const command_rec module_directives[] = {
|
||||
"whether or not to intercept only GET and HEAD requess. Defaults to true."
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecPdfProtectMethod",
|
||||
cmd_pdf_protect_method,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
"protection method to use. Can be 'TokenRedirection' (default) or 'ForcedDownload'"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecGeoLookupsDb",
|
||||
cmd_geo_lookups_db,
|
||||
|
@ -412,6 +412,7 @@ struct directory_config {
|
||||
int pdfp_timeout;
|
||||
const char *pdfp_token_name;
|
||||
int pdfp_only_get;
|
||||
int pdfp_method;
|
||||
|
||||
/* Geo Lookup */
|
||||
geo_db *geo;
|
||||
|
@ -225,11 +225,14 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
if (msr == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, f->r->server,
|
||||
"ModSecurity: Internal Error: Unable to retrieve context in PDF output filter.");
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return send_error_bucket(f, HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (msr->txcfg->pdfp_enabled == 1) {
|
||||
// TODO Should we look at err_headers_out too?
|
||||
const char *h_content_type = apr_table_get(f->r->headers_out, "Content-Type");
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
@ -258,7 +261,7 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
|
||||
// TODO application/x-pdf, application/vnd.fdf, application/vnd.adobe.xfdf,
|
||||
// application/vnd.adobe.xdp+xml, application/vnd.adobe.xfd+xml, application/vnd.pdf
|
||||
// application/acrobat, text/pdf, text/x-pdf
|
||||
// application/acrobat, text/pdf, text/x-pdf ???
|
||||
if (((f->r->content_type != NULL)&&(strcasecmp(f->r->content_type, "application/pdf") == 0))
|
||||
|| ((h_content_type != NULL)&&(strcasecmp(h_content_type, "application/pdf") == 0)))
|
||||
{
|
||||
@ -270,13 +273,32 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
log_escape_nq(msr->mp, r->uri));
|
||||
}
|
||||
|
||||
/* If we are configured with ForcedDownload protection method then we
|
||||
* can do our thing here and finish early.
|
||||
*/
|
||||
if (msr->txcfg->pdfp_method == PDF_PROTECT_METHOD_FORCED_DOWNLOAD) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: Forcing download of a dynamically "
|
||||
"generated PDF file.");
|
||||
}
|
||||
|
||||
apr_table_set(f->r->headers_out, "Content-Disposition", DISPOSITION_VALUE);
|
||||
f->r->content_type = ATTACHMENT_MIME_TYPE;
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return ap_pass_brigade(f->next, bb_in);
|
||||
}
|
||||
|
||||
/* If we are here that means TokenRedirection is the desired protection method. */
|
||||
|
||||
/* Is this a non-GET request? */
|
||||
if ((f->r->method_number != M_GET)&&
|
||||
((msr->txcfg->pdfp_only_get == 1)||(msr->txcfg->pdfp_only_get == -1))
|
||||
) {
|
||||
/* This is a non-GET request and we have been configured
|
||||
* not to intercept it. We are not going to do that but
|
||||
* we are going to tweak the headers to force download.
|
||||
* not to intercept it. So we are going to tweak the headers
|
||||
* to force download.
|
||||
*/
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "PdfProtect: Forcing download of a dynamically "
|
||||
@ -287,6 +309,7 @@ apr_status_t pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
|
||||
f->r->content_type = ATTACHMENT_MIME_TYPE;
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
|
||||
return ap_pass_brigade(f->next, bb_in);
|
||||
}
|
||||
|
||||
@ -362,6 +385,15 @@ int pdfp_check(modsec_rec *msr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msr->txcfg->pdfp_method != PDF_PROTECT_METHOD_TOKEN_REDIRECTION) {
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "PdfProtect: Configured with ForcedDownload as protection method, "
|
||||
"skipping detection on the inbound.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Then determine whether we need to act at
|
||||
* all. If the request is not for a PDF file
|
||||
* return straight away.
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef _PDF_PROTECT_H_
|
||||
#define _PDF_PROTECT_H_
|
||||
|
||||
#define PDF_PROTECT_METHOD_TOKEN_REDIRECTION 1
|
||||
#define PDF_PROTECT_METHOD_FORCED_DOWNLOAD 2
|
||||
|
||||
apr_status_t DSOLOCAL pdfp_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in);
|
||||
|
||||
int DSOLOCAL pdfp_check(modsec_rec *msr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user