diff options
author | Sebastian Pipping <sebastian@pipping.org> | 2021-04-17 17:26:17 +0200 |
---|---|---|
committer | Sebastian Pipping <sebastian@pipping.org> | 2021-05-07 18:25:07 +0200 |
commit | c6223b3b0f3d8e6a37b5775b44eeded02e9c3ea7 (patch) | |
tree | 35368202189783970fca561a6c009903022a1333 | |
parent | 65cddaa4e93263fb88261b60f97cf29f1589d038 (diff) | |
download | libexpat-git-c6223b3b0f3d8e6a37b5775b44eeded02e9c3ea7.tar.gz |
xmlwf: Add support for custom attack protection parameters
-rw-r--r-- | expat/xmlwf/xmltchar.h | 6 | ||||
-rw-r--r-- | expat/xmlwf/xmlwf.c | 69 | ||||
-rwxr-xr-x | expat/xmlwf/xmlwf_helpgen.py | 8 |
3 files changed, 82 insertions, 1 deletions
diff --git a/expat/xmlwf/xmltchar.h b/expat/xmlwf/xmltchar.h index 4843fbe7..30283d08 100644 --- a/expat/xmlwf/xmltchar.h +++ b/expat/xmlwf/xmltchar.h @@ -7,7 +7,7 @@ |_| XML parser Copyright (c) 1997-2000 Thai Open Source Software Center Ltd - Copyright (c) 2016-2017 Sebastian Pipping <sebastian@pipping.org> + Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org> Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk> Licensed under the MIT license: @@ -55,6 +55,8 @@ # define tmain wmain # define tremove _wremove # define tchar wchar_t +# define tcstof wcstof +# define tcstoull wcstoull #else /* not XML_UNICODE */ # define T(x) x # define ftprintf fprintf @@ -72,4 +74,6 @@ # define tmain main # define tremove remove # define tchar char +# define tcstof strtof +# define tcstoull strtoull #endif /* not XML_UNICODE */ diff --git a/expat/xmlwf/xmlwf.c b/expat/xmlwf/xmlwf.c index 2b869667..342d6c59 100644 --- a/expat/xmlwf/xmlwf.c +++ b/expat/xmlwf/xmlwf.c @@ -46,6 +46,8 @@ #include <stdlib.h> #include <stddef.h> #include <string.h> +#include <math.h> /* for isnan */ +#include <errno.h> #include "expat.h" #include "codepage.h" @@ -905,6 +907,12 @@ usage(const XML_Char *prog, int rc) { T(" -t write no XML output for [t]iming of plain parsing\n") T(" -N enable adding doctype and [n]otation declarations\n") T("\n") + T("billion laughs attack protection:\n") + T(" NOTE: If you ever need to increase these values for non-attack payload, please file a bug report.\n") + T("\n") + T(" -a FACTOR set maximum tolerated [a]mplification factor (default: 100.0)\n") + T(" -b BYTES set number of output [b]ytes needed to activate (default: 8 MiB)\n") + T("\n") T("info arguments:\n") T(" -h show this [h]elp message and exit\n") T(" -v show program's [v]ersion number and exit\n") @@ -953,6 +961,11 @@ tmain(int argc, XML_Char **argv) { int requireStandalone = 0; int requiresNotations = 0; int continueOnError = 0; + + float attackMaximumAmplification = -1.0f; /* signaling "not set" */ + unsigned long long attackThresholdBytes; + XML_Bool attackThresholdGiven = XML_FALSE; + int exitCode = XMLWF_EXIT_SUCCESS; enum XML_ParamEntityParsing paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; @@ -1032,6 +1045,49 @@ tmain(int argc, XML_Char **argv) { continueOnError = 1; j++; break; + case T('a'): { + const XML_Char *valueText = NULL; + XMLWF_SHIFT_ARG_INTO(valueText, argc, argv, i, j); + + errno = 0; + XML_Char *afterValueText = (XML_Char *)valueText; + attackMaximumAmplification = tcstof(valueText, &afterValueText); + if ((errno != 0) || (afterValueText[0] != T('\0')) + || isnan(attackMaximumAmplification) + || (attackMaximumAmplification < 1.0f)) { + // This prevents tperror(..) from reporting misleading "[..]: Success" + errno = ERANGE; + tperror(T("invalid amplification limit") T( + " (needs a floating point number greater or equal than 1.0)")); + exit(XMLWF_EXIT_USAGE_ERROR); + } +#ifndef XML_DTD + ftprintf(stderr, T("Warning: Given amplification limit ignored") T( + ", xmlwf has been compiled without DTD support.\n")); +#endif + break; + } + case T('b'): { + const XML_Char *valueText = NULL; + XMLWF_SHIFT_ARG_INTO(valueText, argc, argv, i, j); + + errno = 0; + XML_Char *afterValueText = (XML_Char *)valueText; + attackThresholdBytes = tcstoull(valueText, &afterValueText, 10); + if ((errno != 0) || (afterValueText[0] != T('\0'))) { + // This prevents tperror(..) from reporting misleading "[..]: Success" + errno = ERANGE; + tperror(T("invalid ignore threshold") + T(" (needs an integer from 0 to 2^64-1)")); + exit(XMLWF_EXIT_USAGE_ERROR); + } + attackThresholdGiven = XML_TRUE; +#ifndef XML_DTD + ftprintf(stderr, T("Warning: Given attack threshold ignored") T( + ", xmlwf has been compiled without DTD support.\n")); +#endif + break; + } case T('\0'): if (j > 1) { i++; @@ -1062,6 +1118,19 @@ tmain(int argc, XML_Char **argv) { exit(XMLWF_EXIT_INTERNAL_ERROR); } + if (attackMaximumAmplification != -1.0f) { +#ifdef XML_DTD + XML_SetBillionLaughsAttackProtectionMaximumAmplification( + parser, attackMaximumAmplification); +#endif + } + if (attackThresholdGiven) { +#ifdef XML_DTD + XML_SetBillionLaughsAttackProtectionActivationThreshold( + parser, attackThresholdBytes); +#endif + } + if (requireStandalone) XML_SetNotStandaloneHandler(parser, notStandalone); XML_SetParamEntityParsing(parser, paramEntityParsing); diff --git a/expat/xmlwf/xmlwf_helpgen.py b/expat/xmlwf/xmlwf_helpgen.py index 8ec8d4ea..c2a527fd 100755 --- a/expat/xmlwf/xmlwf_helpgen.py +++ b/expat/xmlwf/xmlwf_helpgen.py @@ -73,6 +73,14 @@ output_mode.add_argument('-m', action='store_true', help='write [m]eta XML, not output_mode.add_argument('-t', action='store_true', help='write no XML output for [t]iming of plain parsing') output_related.add_argument('-N', action='store_true', help='enable adding doctype and [n]otation declarations') +billion_laughs = parser.add_argument_group('billion laughs attack protection', + description='NOTE: ' + 'If you ever need to increase these values ' + 'for non-attack payload, please file a bug report.') +billion_laughs.add_argument('-a', metavar='FACTOR', + help='set maximum tolerated [a]mplification factor (default: 100.0)') +billion_laughs.add_argument('-b', metavar='BYTES', help='set number of output [b]ytes needed to activate (default: 8 MiB)') + parser.add_argument('files', metavar='FILE', nargs='*', help='file to process (default: STDIN)') info = parser.add_argument_group('info arguments') |