Skip to content

Commit 85c8760

Browse files
authored
Merge pull request #2915 from martinhsv/v3/master
Fix: Lua scripts cannot read whole collection at once
2 parents 63bbf62 + b8e1aed commit 85c8760

File tree

4 files changed

+247
-162
lines changed

4 files changed

+247
-162
lines changed

Diff for: CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
v3.x.y - YYYY-MMM-DD (to be released)
22
-------------------------------------
33

4+
- Fix: Lua scripts cannot read whole collection at once
5+
[Issue #2900 - @udi-aharon, @airween, @martinhsv]
46
- Fix: quoted Include config with wildcard
57
[Issue #2905 - @wiseelf, @airween, @martinhsv]
68
- Support isolated PCRE match limits

Diff for: src/variables/variable.h

+188-156
Original file line numberDiff line numberDiff line change
@@ -179,167 +179,199 @@ class VariableMonkeyResolution {
179179
static void stringMatchResolveMulti(Transaction *t,
180180
const std::string &variable,
181181
std::vector<const VariableValue *> *l) {
182-
size_t collection = variable.find(".");
183-
if (collection == std::string::npos) {
184-
collection = variable.find(":");
182+
size_t collection_delimiter_offset = variable.find(".");
183+
if (collection_delimiter_offset == std::string::npos) {
184+
collection_delimiter_offset = variable.find(":");
185185
}
186-
if (collection == std::string::npos) {
187-
if (comp(variable, "RESPONSE_CONTENT_TYPE")) {
188-
t->m_variableResponseContentType.evaluate(l);
189-
} else if (comp(variable, "ARGS_COMBINED_SIZE")) {
190-
t->m_variableARGScombinedSize.evaluate(l);
191-
} else if (comp(variable, "AUTH_TYPE")) {
192-
t->m_variableAuthType.evaluate(l);
193-
} else if (comp(variable, "FILES_COMBINED_SIZE")) {
194-
t->m_variableFilesCombinedSize.evaluate(l);
195-
} else if (comp(variable, "FULL_REQUEST")) {
196-
t->m_variableFullRequest.evaluate(l);
197-
} else if (comp(variable, "FULL_REQUEST_LENGTH")) {
198-
t->m_variableFullRequestLength.evaluate(l);
199-
} else if (comp(variable, "INBOUND_DATA_ERROR")) {
200-
t->m_variableInboundDataError.evaluate(l);
201-
} else if (comp(variable, "MATCHED_VAR")) {
202-
t->m_variableMatchedVar.evaluate(l);
203-
} else if (comp(variable, "MATCHED_VAR_NAME")) {
204-
t->m_variableMatchedVarName.evaluate(l);
205-
} else if (comp(variable, "MSC_PCRE_ERROR")) {
206-
t->m_variableMscPcreError.evaluate(l);
207-
} else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) {
208-
t->m_variableMscPcreLimitsExceeded.evaluate(l);
209-
} else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) {
210-
t->m_variableMultipartCrlfLFLines.evaluate(l);
211-
} else if (comp(variable, "MULTIPART_DATA_AFTER")) {
212-
t->m_variableMultipartDataAfter.evaluate(l);
213-
} else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) {
214-
t->m_variableMultipartFileLimitExceeded.evaluate(l);
215-
} else if (comp(variable, "MULTIPART_STRICT_ERROR")) {
216-
t->m_variableMultipartStrictError.evaluate(l);
217-
} else if (comp(variable, "MULTIPART_HEADER_FOLDING")) {
218-
t->m_variableMultipartHeaderFolding.evaluate(l);
219-
} else if (comp(variable, "MULTIPART_INVALID_QUOTING")) {
220-
t->m_variableMultipartInvalidQuoting.evaluate(l);
221-
} else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) {
222-
t->m_variableMultipartInvalidHeaderFolding.evaluate(l);
223-
} else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) {
224-
t->m_variableMultipartUnmatchedBoundary.evaluate(l);
225-
} else if (comp(variable, "OUTBOUND_DATA_ERROR")) {
226-
t->m_variableOutboundDataError.evaluate(l);
227-
} else if (comp(variable, "PATH_INFO")) {
228-
t->m_variablePathInfo.evaluate(l);
229-
} else if (comp(variable, "QUERY_STRING")) {
230-
t->m_variableQueryString.evaluate(l);
231-
} else if (comp(variable, "REMOTE_ADDR")) {
232-
t->m_variableRemoteAddr.evaluate(l);
233-
} else if (comp(variable, "REMOTE_HOST")) {
234-
t->m_variableRemoteHost.evaluate(l);
235-
} else if (comp(variable, "REMOTE_PORT")) {
236-
t->m_variableRemotePort.evaluate(l);
237-
} else if (comp(variable, "REQBODY_ERROR")) {
238-
t->m_variableReqbodyError.evaluate(l);
239-
} else if (comp(variable, "REQBODY_ERROR_MSG")) {
240-
t->m_variableReqbodyErrorMsg.evaluate(l);
241-
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) {
242-
t->m_variableReqbodyProcessorErrorMsg.evaluate(l);
243-
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) {
244-
t->m_variableReqbodyProcessorError.evaluate(l);
245-
} else if (comp(variable, "REQBODY_PROCESSOR")) {
246-
t->m_variableReqbodyProcessor.evaluate(l);
247-
} else if (comp(variable, "REQUEST_BASENAME")) {
248-
t->m_variableRequestBasename.evaluate(l);
249-
} else if (comp(variable, "REQUEST_BODY")) {
250-
t->m_variableRequestBody.evaluate(l);
251-
} else if (comp(variable, "REQUEST_BODY_LENGTH")) {
252-
t->m_variableRequestBodyLength.evaluate(l);
253-
} else if (comp(variable, "REQUEST_FILENAME")) {
254-
t->m_variableRequestFilename.evaluate(l);
255-
} else if (comp(variable, "REQUEST_LINE")) {
256-
t->m_variableRequestLine.evaluate(l);
257-
} else if (comp(variable, "REQUEST_METHOD")) {
258-
t->m_variableRequestMethod.evaluate(l);
259-
} else if (comp(variable, "REQUEST_PROTOCOL")) {
260-
t->m_variableRequestProtocol.evaluate(l);
261-
} else if (comp(variable, "REQUEST_URI")) {
262-
t->m_variableRequestURI.evaluate(l);
263-
} else if (comp(variable, "REQUEST_URI_RAW")) {
264-
t->m_variableRequestURIRaw.evaluate(l);
265-
} else if (comp(variable, "RESOURCE")) {
266-
t->m_variableResource.evaluate(l);
267-
} else if (comp(variable, "RESPONSE_BODY")) {
268-
t->m_variableResponseBody.evaluate(l);
269-
} else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) {
270-
t->m_variableResponseContentLength.evaluate(l);
271-
} else if (comp(variable, "RESPONSE_PROTOCOL")) {
272-
t->m_variableResponseProtocol.evaluate(l);
273-
} else if (comp(variable, "RESPONSE_STATUS")) {
274-
t->m_variableResponseStatus.evaluate(l);
275-
} else if (comp(variable, "SERVER_ADDR")) {
276-
t->m_variableServerAddr.evaluate(l);
277-
} else if (comp(variable, "SERVER_NAME")) {
278-
t->m_variableServerName.evaluate(l);
279-
} else if (comp(variable, "SERVER_PORT")) {
280-
t->m_variableServerPort.evaluate(l);
281-
} else if (comp(variable, "SESSIONID")) {
282-
t->m_variableSessionID.evaluate(l);
283-
} else if (comp(variable, "UNIQUE_ID")) {
284-
t->m_variableUniqueID.evaluate(l);
285-
} else if (comp(variable, "URLENCODED_ERROR")) {
286-
t->m_variableUrlEncodedError.evaluate(l);
287-
} else if (comp(variable, "USERID")) {
288-
t->m_variableUserID.evaluate(l);
186+
std::string col; // collection name excluding individual variable specification
187+
std::string var; // variable within the collection
188+
if (collection_delimiter_offset == std::string::npos) {
189+
col = variable;
190+
} else {
191+
col = std::string(variable, 0, collection_delimiter_offset);
192+
var = std::string(variable, collection_delimiter_offset + 1,
193+
variable.length() - (collection_delimiter_offset + 1));
194+
}
195+
196+
// First check if the request is for a collection of type AnchoredSetVariable
197+
AnchoredSetVariable* anchoredSetVariable = NULL;
198+
if (comp(col, "ARGS")) {
199+
anchoredSetVariable = &t->m_variableArgs;
200+
} else if (comp(col, "ARGS_GET")) {
201+
anchoredSetVariable = &t->m_variableArgsGet;
202+
} else if (comp(col, "ARGS_POST")) {
203+
anchoredSetVariable = &t->m_variableArgsPost;
204+
} else if (comp(col, "FILES_SIZES")) {
205+
anchoredSetVariable = &t->m_variableFilesSizes;
206+
} else if (comp(col, "FILES_NAMES")) {
207+
anchoredSetVariable = &t->m_variableFilesNames;
208+
} else if (comp(col, "FILES_TMP_CONTENT")) {
209+
anchoredSetVariable = &t->m_variableFilesTmpContent;
210+
} else if (comp(col, "MULTIPART_FILENAME")) {
211+
anchoredSetVariable = &t->m_variableMultipartFileName;
212+
} else if (comp(col, "MULTIPART_NAME")) {
213+
anchoredSetVariable = &t->m_variableMultipartName;
214+
} else if (comp(col, "MATCHED_VARS_NAMES")) {
215+
anchoredSetVariable = &t->m_variableMatchedVarsNames;
216+
} else if (comp(col, "MATCHED_VARS")) {
217+
anchoredSetVariable = &t->m_variableMatchedVars;
218+
} else if (comp(col, "FILES")) {
219+
anchoredSetVariable = &t->m_variableFiles;
220+
} else if (comp(col, "REQUEST_COOKIES")) {
221+
anchoredSetVariable = &t->m_variableRequestCookies;
222+
} else if (comp(col, "REQUEST_HEADERS")) {
223+
anchoredSetVariable = &t->m_variableRequestHeaders;
224+
} else if (comp(variable, "REQUEST_HEADERS_NAMES")) {
225+
anchoredSetVariable = &t->m_variableRequestHeadersNames;
226+
} else if (comp(col, "RESPONSE_HEADERS")) {
227+
anchoredSetVariable = &t->m_variableResponseHeaders;
228+
} else if (comp(variable, "RESPONSE_HEADERS_NAMES")) {
229+
anchoredSetVariable = &t->m_variableResponseHeadersNames;
230+
} else if (comp(col, "GEO")) {
231+
anchoredSetVariable = &t->m_variableGeo;
232+
} else if (comp(col, "REQUEST_COOKIES_NAMES")) {
233+
anchoredSetVariable = &t->m_variableRequestCookiesNames;
234+
} else if (comp(col, "FILES_TMPNAMES")) {
235+
anchoredSetVariable = &t->m_variableFilesTmpNames;
236+
}
237+
if (anchoredSetVariable != NULL) {
238+
if (collection_delimiter_offset == std::string::npos) {
239+
anchoredSetVariable->resolve(l);
289240
} else {
290-
throw std::invalid_argument("Variable not found.");
241+
anchoredSetVariable->resolve(var, l);
291242
}
292-
} else {
293-
std::string col = std::string(variable, 0, collection);
294-
std::string var = std::string(variable, collection + 1,
295-
variable.length() - (collection + 1));
296-
if (comp(col, "ARGS")) {
297-
t->m_variableArgs.resolve(var, l);
298-
} else if (comp(variable, "ARGS_NAMES")) {
299-
t->m_variableArgsNames.resolve(var, l);
300-
} else if (comp(variable, "ARGS_GET_NAMES")) {
301-
t->m_variableArgsGetNames.resolve(var, l);
302-
} else if (comp(variable, "ARGS_POST_NAMES")) {
303-
t->m_variableArgsPostNames.resolve(var, l);
304-
} else if (comp(col, "ARGS_GET")) {
305-
t->m_variableArgsGet.resolve(var, l);
306-
} else if (comp(col, "ARGS_POST")) {
307-
t->m_variableArgsPost.resolve(var, l);
308-
} else if (comp(col, "FILES_SIZES")) {
309-
t->m_variableFilesSizes.resolve(var, l);
310-
} else if (comp(col, "FILES_NAMES")) {
311-
t->m_variableFilesNames.resolve(var, l);
312-
} else if (comp(col, "FILES_TMP_CONTENT")) {
313-
t->m_variableFilesTmpContent.resolve(var, l);
314-
} else if (comp(col, "MULTIPART_FILENAME")) {
315-
t->m_variableMultipartFileName.resolve(var, l);
316-
} else if (comp(col, "MULTIPART_NAME")) {
317-
t->m_variableMultipartName.resolve(var, l);
318-
} else if (comp(col, "MATCHED_VARS_NAMES")) {
319-
t->m_variableMatchedVarsNames.resolve(var, l);
320-
} else if (comp(col, "MATCHED_VARS")) {
321-
t->m_variableMatchedVars.resolve(var, l);
322-
} else if (comp(col, "FILES")) {
323-
t->m_variableFiles.resolve(var, l);
324-
} else if (comp(col, "REQUEST_COOKIES")) {
325-
t->m_variableRequestCookies.resolve(var, l);
326-
} else if (comp(col, "REQUEST_HEADERS")) {
327-
t->m_variableRequestHeaders.resolve(var, l);
328-
} else if (comp(variable, "REQUEST_HEADERS_NAMES")) {
329-
t->m_variableRequestHeadersNames.resolve(var, l);
330-
} else if (comp(col, "RESPONSE_HEADERS")) {
331-
t->m_variableResponseHeaders.resolve(var, l);
332-
} else if (comp(variable, "RESPONSE_HEADERS_NAMES")) {
333-
t->m_variableResponseHeadersNames.resolve(var, l);
334-
} else if (comp(col, "GEO")) {
335-
t->m_variableGeo.resolve(var, l);
336-
} else if (comp(col, "REQUEST_COOKIES_NAMES")) {
337-
t->m_variableRequestCookiesNames.resolve(var, l);
338-
} else if (comp(col, "FILES_TMPNAMES")) {
339-
t->m_variableFilesTmpNames.resolve(var, l);
243+
return;
244+
}
245+
246+
// Next check for collection of type AnchoredSetVariableTranslationProxy
247+
AnchoredSetVariableTranslationProxy* anchoredSetVariableTranslationProxy = NULL;
248+
if (comp(col, "ARGS_NAMES")) {
249+
anchoredSetVariableTranslationProxy = &t->m_variableArgsNames;
250+
} else if (comp(col, "ARGS_GET_NAMES")) {
251+
anchoredSetVariableTranslationProxy = &t->m_variableArgsGetNames;
252+
} else if (comp(col, "ARGS_POST_NAMES")) {
253+
anchoredSetVariableTranslationProxy = &t->m_variableArgsPostNames;
254+
}
255+
if (anchoredSetVariableTranslationProxy != NULL) {
256+
if (collection_delimiter_offset == std::string::npos) {
257+
anchoredSetVariableTranslationProxy->resolve(l);
340258
} else {
341-
throw std::invalid_argument("Variable not found.");
259+
anchoredSetVariableTranslationProxy->resolve(var, l);
342260
}
261+
return;
262+
}
263+
264+
265+
// It could still be a non-collection variable, but in that case
266+
// there should not be a request for a variable-within-a-collection
267+
if (collection_delimiter_offset != std::string::npos) {
268+
throw std::invalid_argument("Variable not found.");
269+
}
270+
271+
if (comp(variable, "RESPONSE_CONTENT_TYPE")) {
272+
t->m_variableResponseContentType.evaluate(l);
273+
} else if (comp(variable, "ARGS_COMBINED_SIZE")) {
274+
t->m_variableARGScombinedSize.evaluate(l);
275+
} else if (comp(variable, "AUTH_TYPE")) {
276+
t->m_variableAuthType.evaluate(l);
277+
} else if (comp(variable, "FILES_COMBINED_SIZE")) {
278+
t->m_variableFilesCombinedSize.evaluate(l);
279+
} else if (comp(variable, "FULL_REQUEST")) {
280+
t->m_variableFullRequest.evaluate(l);
281+
} else if (comp(variable, "FULL_REQUEST_LENGTH")) {
282+
t->m_variableFullRequestLength.evaluate(l);
283+
} else if (comp(variable, "INBOUND_DATA_ERROR")) {
284+
t->m_variableInboundDataError.evaluate(l);
285+
} else if (comp(variable, "MATCHED_VAR")) {
286+
t->m_variableMatchedVar.evaluate(l);
287+
} else if (comp(variable, "MATCHED_VAR_NAME")) {
288+
t->m_variableMatchedVarName.evaluate(l);
289+
} else if (comp(variable, "MSC_PCRE_ERROR")) {
290+
t->m_variableMscPcreError.evaluate(l);
291+
} else if (comp(variable, "MSC_PCRE_LIMITS_EXCEEDED")) {
292+
t->m_variableMscPcreLimitsExceeded.evaluate(l);
293+
} else if (comp(variable, "MULTIPART_CRLF_LF_LINES")) {
294+
t->m_variableMultipartCrlfLFLines.evaluate(l);
295+
} else if (comp(variable, "MULTIPART_DATA_AFTER")) {
296+
t->m_variableMultipartDataAfter.evaluate(l);
297+
} else if (comp(variable, "MULTIPART_FILE_LIMIT_EXCEEDED")) {
298+
t->m_variableMultipartFileLimitExceeded.evaluate(l);
299+
} else if (comp(variable, "MULTIPART_STRICT_ERROR")) {
300+
t->m_variableMultipartStrictError.evaluate(l);
301+
} else if (comp(variable, "MULTIPART_HEADER_FOLDING")) {
302+
t->m_variableMultipartHeaderFolding.evaluate(l);
303+
} else if (comp(variable, "MULTIPART_INVALID_QUOTING")) {
304+
t->m_variableMultipartInvalidQuoting.evaluate(l);
305+
} else if (comp(variable, "MULTIPART_INVALID_HEADER_FOLDING")) {
306+
t->m_variableMultipartInvalidHeaderFolding.evaluate(l);
307+
} else if (comp(variable, "MULTIPART_UNMATCHED_BOUNDARY")) {
308+
t->m_variableMultipartUnmatchedBoundary.evaluate(l);
309+
} else if (comp(variable, "OUTBOUND_DATA_ERROR")) {
310+
t->m_variableOutboundDataError.evaluate(l);
311+
} else if (comp(variable, "PATH_INFO")) {
312+
t->m_variablePathInfo.evaluate(l);
313+
} else if (comp(variable, "QUERY_STRING")) {
314+
t->m_variableQueryString.evaluate(l);
315+
} else if (comp(variable, "REMOTE_ADDR")) {
316+
t->m_variableRemoteAddr.evaluate(l);
317+
} else if (comp(variable, "REMOTE_HOST")) {
318+
t->m_variableRemoteHost.evaluate(l);
319+
} else if (comp(variable, "REMOTE_PORT")) {
320+
t->m_variableRemotePort.evaluate(l);
321+
} else if (comp(variable, "REQBODY_ERROR")) {
322+
t->m_variableReqbodyError.evaluate(l);
323+
} else if (comp(variable, "REQBODY_ERROR_MSG")) {
324+
t->m_variableReqbodyErrorMsg.evaluate(l);
325+
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR_MSG")) {
326+
t->m_variableReqbodyProcessorErrorMsg.evaluate(l);
327+
} else if (comp(variable, "REQBODY_PROCESSOR_ERROR")) {
328+
t->m_variableReqbodyProcessorError.evaluate(l);
329+
} else if (comp(variable, "REQBODY_PROCESSOR")) {
330+
t->m_variableReqbodyProcessor.evaluate(l);
331+
} else if (comp(variable, "REQUEST_BASENAME")) {
332+
t->m_variableRequestBasename.evaluate(l);
333+
} else if (comp(variable, "REQUEST_BODY")) {
334+
t->m_variableRequestBody.evaluate(l);
335+
} else if (comp(variable, "REQUEST_BODY_LENGTH")) {
336+
t->m_variableRequestBodyLength.evaluate(l);
337+
} else if (comp(variable, "REQUEST_FILENAME")) {
338+
t->m_variableRequestFilename.evaluate(l);
339+
} else if (comp(variable, "REQUEST_LINE")) {
340+
t->m_variableRequestLine.evaluate(l);
341+
} else if (comp(variable, "REQUEST_METHOD")) {
342+
t->m_variableRequestMethod.evaluate(l);
343+
} else if (comp(variable, "REQUEST_PROTOCOL")) {
344+
t->m_variableRequestProtocol.evaluate(l);
345+
} else if (comp(variable, "REQUEST_URI")) {
346+
t->m_variableRequestURI.evaluate(l);
347+
} else if (comp(variable, "REQUEST_URI_RAW")) {
348+
t->m_variableRequestURIRaw.evaluate(l);
349+
} else if (comp(variable, "RESOURCE")) {
350+
t->m_variableResource.evaluate(l);
351+
} else if (comp(variable, "RESPONSE_BODY")) {
352+
t->m_variableResponseBody.evaluate(l);
353+
} else if (comp(variable, "RESPONSE_CONTENT_LENGTH")) {
354+
t->m_variableResponseContentLength.evaluate(l);
355+
} else if (comp(variable, "RESPONSE_PROTOCOL")) {
356+
t->m_variableResponseProtocol.evaluate(l);
357+
} else if (comp(variable, "RESPONSE_STATUS")) {
358+
t->m_variableResponseStatus.evaluate(l);
359+
} else if (comp(variable, "SERVER_ADDR")) {
360+
t->m_variableServerAddr.evaluate(l);
361+
} else if (comp(variable, "SERVER_NAME")) {
362+
t->m_variableServerName.evaluate(l);
363+
} else if (comp(variable, "SERVER_PORT")) {
364+
t->m_variableServerPort.evaluate(l);
365+
} else if (comp(variable, "SESSIONID")) {
366+
t->m_variableSessionID.evaluate(l);
367+
} else if (comp(variable, "UNIQUE_ID")) {
368+
t->m_variableUniqueID.evaluate(l);
369+
} else if (comp(variable, "URLENCODED_ERROR")) {
370+
t->m_variableUrlEncodedError.evaluate(l);
371+
} else if (comp(variable, "USERID")) {
372+
t->m_variableUserID.evaluate(l);
373+
} else {
374+
throw std::invalid_argument("Variable not found.");
343375
}
344376
}
345377

Diff for: test/test-cases/data/match-getvars-args.lua

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function main()
2+
local d = m.getvars("ARGS");
3+
local size = #d;
4+
m.log(9,"ARGS count read =" .. tostring(size));
5+
6+
ret = nil
7+
8+
if ( #d == 2 ) then
9+
return nil
10+
end
11+
12+
return "Unexpected result"
13+
end

0 commit comments

Comments
 (0)