• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.72
/src/detect-http-cookie.c
1
/* Copyright (C) 2007-2018 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \ingroup httplayer
20
 *
21
 * @{
22
 */
23

24

25
/**
26
 * \file
27
 *
28
 * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
29
 *
30
 * Implements the http_cookie keyword
31
 */
32

33
#include "suricata-common.h"
34
#include "threads.h"
35
#include "decode.h"
36
#include "detect.h"
37

38
#include "detect-parse.h"
39
#include "detect-engine.h"
40
#include "detect-engine-buffer.h"
41
#include "detect-engine-mpm.h"
42
#include "detect-engine-prefilter.h"
43
#include "detect-content.h"
44
#include "detect-pcre.h"
45

46
#include "flow.h"
47
#include "flow-var.h"
48
#include "flow-util.h"
49

50
#include "util-debug.h"
51
#include "util-error.h"
52
#include "util-unittest.h"
53
#include "util-unittest-helper.h"
54
#include "util-spm.h"
55
#include "util-print.h"
56

57
#include "app-layer.h"
58
#include "app-layer-parser.h"
59

60
#include "app-layer-htp.h"
61
#include "detect-http-cookie.h"
62
#include "stream-tcp.h"
63

64
static int DetectHttpCookieSetup (DetectEngineCtx *, Signature *, const char *);
65
static int DetectHttpCookieSetupSticky (DetectEngineCtx *, Signature *, const char *);
66
#ifdef UNITTESTS
67
static void DetectHttpCookieRegisterTests(void);
68
#endif
69
static int g_http_cookie_buffer_id = 0;
70
static int g_http2_thread_id = 0;
71

72
static InspectionBuffer *GetRequestData(DetectEngineThreadCtx *det_ctx,
73
        const DetectEngineTransforms *transforms,
74
        Flow *_f, const uint8_t _flow_flags,
75
        void *txv, const int list_id);
76
static InspectionBuffer *GetResponseData(DetectEngineThreadCtx *det_ctx,
77
        const DetectEngineTransforms *transforms,
78
        Flow *_f, const uint8_t _flow_flags,
79
        void *txv, const int list_id);
80
static InspectionBuffer *GetRequestData2(DetectEngineThreadCtx *det_ctx,
81
        const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
82
        const int list_id);
83
static InspectionBuffer *GetResponseData2(DetectEngineThreadCtx *det_ctx,
84
        const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
85
        const int list_id);
86
/**
87
 * \brief Registration function for keyword: http_cookie
88
 */
89
void DetectHttpCookieRegister(void)
90
{
3✔
91
    /* http_cookie content modifier */
92
    sigmatch_table[DETECT_HTTP_COOKIE_CM].name = "http_cookie";
3✔
93
    sigmatch_table[DETECT_HTTP_COOKIE_CM].desc =
3✔
94
            "content modifier to match only on the HTTP cookie-buffer";
3✔
95
    sigmatch_table[DETECT_HTTP_COOKIE_CM].url = "/rules/http-keywords.html#http-cookie";
3✔
96
    sigmatch_table[DETECT_HTTP_COOKIE_CM].Setup = DetectHttpCookieSetup;
3✔
97
#ifdef UNITTESTS
98
    sigmatch_table[DETECT_HTTP_COOKIE_CM].RegisterTests = DetectHttpCookieRegisterTests;
99
#endif
100
    sigmatch_table[DETECT_HTTP_COOKIE_CM].flags |= SIGMATCH_NOOPT;
3✔
101
    sigmatch_table[DETECT_HTTP_COOKIE_CM].flags |= SIGMATCH_INFO_CONTENT_MODIFIER;
3✔
102
    sigmatch_table[DETECT_HTTP_COOKIE_CM].alternative = DETECT_HTTP_COOKIE;
3✔
103

104
    /* http.cookie sticky buffer */
105
    sigmatch_table[DETECT_HTTP_COOKIE].name = "http.cookie";
3✔
106
    sigmatch_table[DETECT_HTTP_COOKIE].desc = "sticky buffer to match on the HTTP Cookie/Set-Cookie buffers";
3✔
107
    sigmatch_table[DETECT_HTTP_COOKIE].url = "/rules/http-keywords.html#http-cookie";
3✔
108
    sigmatch_table[DETECT_HTTP_COOKIE].Setup = DetectHttpCookieSetupSticky;
3✔
109
    sigmatch_table[DETECT_HTTP_COOKIE].flags |= SIGMATCH_NOOPT;
3✔
110
    sigmatch_table[DETECT_HTTP_COOKIE].flags |= SIGMATCH_INFO_STICKY_BUFFER;
3✔
111

112
    DetectAppLayerInspectEngineRegister("http_cookie", ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
3✔
113
            HTP_REQUEST_PROGRESS_HEADERS, DetectEngineInspectBufferGeneric, GetRequestData);
3✔
114
    DetectAppLayerInspectEngineRegister("http_cookie", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
3✔
115
            HTP_REQUEST_PROGRESS_HEADERS, DetectEngineInspectBufferGeneric, GetResponseData);
3✔
116

117
    DetectAppLayerMpmRegister("http_cookie", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
3✔
118
            GetRequestData, ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_HEADERS);
3✔
119
    DetectAppLayerMpmRegister("http_cookie", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
3✔
120
            GetResponseData, ALPROTO_HTTP1, HTP_REQUEST_PROGRESS_HEADERS);
3✔
121

122
    DetectAppLayerInspectEngineRegister("http_cookie", ALPROTO_HTTP2, SIG_FLAG_TOSERVER,
3✔
123
            HTTP2StateDataClient, DetectEngineInspectBufferGeneric, GetRequestData2);
3✔
124
    DetectAppLayerInspectEngineRegister("http_cookie", ALPROTO_HTTP2, SIG_FLAG_TOCLIENT,
3✔
125
            HTTP2StateDataServer, DetectEngineInspectBufferGeneric, GetResponseData2);
3✔
126

127
    DetectAppLayerMpmRegister("http_cookie", SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister,
3✔
128
            GetRequestData2, ALPROTO_HTTP2, HTTP2StateDataClient);
3✔
129
    DetectAppLayerMpmRegister("http_cookie", SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister,
3✔
130
            GetResponseData2, ALPROTO_HTTP2, HTTP2StateDataServer);
3✔
131

132
    DetectBufferTypeSetDescriptionByName("http_cookie",
3✔
133
            "http cookie header");
3✔
134

135
    g_http2_thread_id = DetectRegisterThreadCtxGlobalFuncs(
3✔
136
            "http_cookie", SCHttp2ThreadBufDataInit, NULL, SCHttp2ThreadBufDataFree);
3✔
137

138
    g_http_cookie_buffer_id = DetectBufferTypeGetByName("http_cookie");
3✔
139
}
3✔
140

141
/**
142
 * \brief this function setups the http_cookie modifier keyword used in the rule
143
 *
144
 * \param de_ctx   Pointer to the Detection Engine Context
145
 * \param s        Pointer to the Signature to which the current keyword belongs
146
 * \param str      Should hold an empty string always
147
 *
148
 * \retval  0 On success
149
 * \retval -1 On failure
150
 */
151

152
static int DetectHttpCookieSetup(DetectEngineCtx *de_ctx, Signature *s, const char *str)
153
{
70✔
154
    return DetectEngineContentModifierBufferSetup(
70✔
155
            de_ctx, s, str, DETECT_HTTP_COOKIE_CM, g_http_cookie_buffer_id, ALPROTO_HTTP1);
70✔
156
}
70✔
157

158
/**
159
 * \brief this function setup the http.cookie keyword used in the rule
160
 *
161
 * \param de_ctx   Pointer to the Detection Engine Context
162
 * \param s        Pointer to the Signature to which the current keyword belongs
163
 * \param str      Should hold an empty string always
164
 *
165
 * \retval 0       On success
166
 */
167
static int DetectHttpCookieSetupSticky(DetectEngineCtx *de_ctx, Signature *s, const char *str)
168
{
5,642✔
169
    if (SCDetectBufferSetActiveList(de_ctx, s, g_http_cookie_buffer_id) < 0)
5,642✔
170
        return -1;
4✔
171

172
    if (SCDetectSignatureSetAppProto(s, ALPROTO_HTTP) < 0)
5,638✔
173
        return -1;
109✔
174

175
    return 0;
5,529✔
176
}
5,638✔
177

178
static InspectionBuffer *GetRequestData(DetectEngineThreadCtx *det_ctx,
179
        const DetectEngineTransforms *transforms, Flow *_f,
180
        const uint8_t _flow_flags, void *txv, const int list_id)
181
{
425✔
182
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
425✔
183
    if (buffer->inspect == NULL) {
425✔
184
        htp_tx_t *tx = (htp_tx_t *)txv;
421✔
185

186
        if (htp_tx_request_headers(tx) == NULL)
421✔
187
            return NULL;
×
188

189
        const htp_header_t *h = htp_tx_request_header(tx, "Cookie");
421✔
190
        if (h == NULL || htp_header_value(h) == NULL) {
421✔
191
            SCLogDebug("HTTP cookie header not present in this request");
195✔
192
            return NULL;
195✔
193
        }
195✔
194

195
        const uint32_t data_len = (uint32_t)htp_header_value_len(h);
226✔
196
        const uint8_t *data = htp_header_value_ptr(h);
226✔
197

198
        InspectionBufferSetupAndApplyTransforms(
226✔
199
                det_ctx, list_id, buffer, data, data_len, transforms);
226✔
200
    }
226✔
201

202
    return buffer;
230✔
203
}
425✔
204

205
static InspectionBuffer *GetResponseData(DetectEngineThreadCtx *det_ctx,
206
        const DetectEngineTransforms *transforms, Flow *_f,
207
        const uint8_t _flow_flags, void *txv, const int list_id)
UNCOV
208
{
×
UNCOV
209
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
×
UNCOV
210
    if (buffer->inspect == NULL) {
×
UNCOV
211
        htp_tx_t *tx = (htp_tx_t *)txv;
×
212

UNCOV
213
        if (htp_tx_response_headers(tx) == NULL)
×
214
            return NULL;
×
215

UNCOV
216
        const htp_header_t *h = htp_tx_response_header(tx, "Set-Cookie");
×
UNCOV
217
        if (h == NULL || htp_header_value(h) == NULL) {
×
UNCOV
218
            SCLogDebug("HTTP cookie header not present in this request");
×
UNCOV
219
            return NULL;
×
UNCOV
220
        }
×
221

UNCOV
222
        const uint32_t data_len = (uint32_t)htp_header_value_len(h);
×
UNCOV
223
        const uint8_t *data = htp_header_value_ptr(h);
×
224

UNCOV
225
        InspectionBufferSetupAndApplyTransforms(
×
UNCOV
226
                det_ctx, list_id, buffer, data, data_len, transforms);
×
UNCOV
227
    }
×
228

UNCOV
229
    return buffer;
×
UNCOV
230
}
×
231

232
static InspectionBuffer *GetRequestData2(DetectEngineThreadCtx *det_ctx,
233
        const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
234
        const int list_id)
235
{
804✔
236
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
804✔
237
    if (buffer->inspect == NULL) {
804✔
238
        uint32_t b_len = 0;
706✔
239
        const uint8_t *b = NULL;
706✔
240

241
        void *thread_buf = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id);
706✔
242
        if (thread_buf == NULL)
706✔
243
            return NULL;
×
244
        if (SCHttp2TxGetCookie(txv, STREAM_TOSERVER, &b, &b_len, thread_buf) != 1)
706✔
245
            return NULL;
597✔
246
        if (b == NULL || b_len == 0)
109✔
247
            return NULL;
×
248

249
        InspectionBufferSetupAndApplyTransforms(det_ctx, list_id, buffer, b, b_len, transforms);
109✔
250
    }
109✔
251

252
    return buffer;
207✔
253
}
804✔
254

255
static InspectionBuffer *GetResponseData2(DetectEngineThreadCtx *det_ctx,
256
        const DetectEngineTransforms *transforms, Flow *_f, const uint8_t _flow_flags, void *txv,
257
        const int list_id)
258
{
502✔
259
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
502✔
260
    if (buffer->inspect == NULL) {
502✔
261
        uint32_t b_len = 0;
502✔
262
        const uint8_t *b = NULL;
502✔
263

264
        void *thread_buf = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, g_http2_thread_id);
502✔
265
        if (thread_buf == NULL)
502✔
266
            return NULL;
×
267
        if (SCHttp2TxGetCookie(txv, STREAM_TOCLIENT, &b, &b_len, thread_buf) != 1)
502✔
268
            return NULL;
502✔
UNCOV
269
        if (b == NULL || b_len == 0)
×
270
            return NULL;
×
271

UNCOV
272
        InspectionBufferSetupAndApplyTransforms(det_ctx, list_id, buffer, b, b_len, transforms);
×
UNCOV
273
    }
×
274

UNCOV
275
    return buffer;
×
276
}
502✔
277

278
/******************************** UNITESTS **********************************/
279

280
#ifdef UNITTESTS
281
#include "tests/detect-http-cookie.c"
282
#endif /* UNITTESTS */
283

284
/**
285
 * @}
286
 */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc