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

jasonish / suricata / 23019292042

12 Mar 2026 07:08PM UTC coverage: 79.245% (-0.004%) from 79.249%
23019292042

push

github

jasonish
github-ci: add schema ordering check for yaml schema

266163 of 335873 relevant lines covered (79.25%)

4877167.7 hits per line

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

94.96
/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
{
2,223✔
91
    /* http_cookie content modifier */
92
    sigmatch_table[DETECT_HTTP_COOKIE_CM].name = "http_cookie";
2,223✔
93
    sigmatch_table[DETECT_HTTP_COOKIE_CM].desc =
2,223✔
94
            "content modifier to match only on the HTTP cookie-buffer";
2,223✔
95
    sigmatch_table[DETECT_HTTP_COOKIE_CM].url = "/rules/http-keywords.html#http-cookie";
2,223✔
96
    sigmatch_table[DETECT_HTTP_COOKIE_CM].Setup = DetectHttpCookieSetup;
2,223✔
97
#ifdef UNITTESTS
3✔
98
    sigmatch_table[DETECT_HTTP_COOKIE_CM].RegisterTests = DetectHttpCookieRegisterTests;
3✔
99
#endif
3✔
100
    sigmatch_table[DETECT_HTTP_COOKIE_CM].flags |= SIGMATCH_NOOPT;
2,223✔
101
    sigmatch_table[DETECT_HTTP_COOKIE_CM].flags |= SIGMATCH_INFO_CONTENT_MODIFIER;
2,223✔
102
    sigmatch_table[DETECT_HTTP_COOKIE_CM].alternative = DETECT_HTTP_COOKIE;
2,223✔
103

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

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

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

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

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

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

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

138
    g_http_cookie_buffer_id = DetectBufferTypeGetByName("http_cookie");
2,223✔
139
}
2,223✔
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
{
177✔
154
    return DetectEngineContentModifierBufferSetup(
177✔
155
            de_ctx, s, str, DETECT_HTTP_COOKIE_CM, g_http_cookie_buffer_id, ALPROTO_HTTP1);
177✔
156
}
177✔
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
{
6,290✔
169
    if (SCDetectBufferSetActiveList(de_ctx, s, g_http_cookie_buffer_id) < 0)
6,290✔
170
        return -1;
4✔
171

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

175
    return 0;
6,177✔
176
}
6,286✔
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
{
2,991✔
182
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
2,991✔
183
    if (buffer->inspect == NULL) {
2,991✔
184
        htp_tx_t *tx = (htp_tx_t *)txv;
2,944✔
185

186
        if (htp_tx_request_headers(tx) == NULL)
2,944✔
187
            return NULL;
×
188

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

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

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

202
    return buffer;
1,349✔
203
}
2,991✔
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)
208
{
2,241✔
209
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
2,241✔
210
    if (buffer->inspect == NULL) {
2,241✔
211
        htp_tx_t *tx = (htp_tx_t *)txv;
2,239✔
212

213
        if (htp_tx_response_headers(tx) == NULL)
2,239✔
214
            return NULL;
×
215

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

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

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

229
    return buffer;
153✔
230
}
2,241✔
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
{
990✔
236
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
990✔
237
    if (buffer->inspect == NULL) {
990✔
238
        uint32_t b_len = 0;
888✔
239
        const uint8_t *b = NULL;
888✔
240

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

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

252
    return buffer;
224✔
253
}
990✔
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
{
704✔
259
    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
704✔
260
    if (buffer->inspect == NULL) {
704✔
261
        uint32_t b_len = 0;
704✔
262
        const uint8_t *b = NULL;
704✔
263

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

272
        InspectionBufferSetupAndApplyTransforms(det_ctx, list_id, buffer, b, b_len, transforms);
1✔
273
    }
1✔
274

275
    return buffer;
1✔
276
}
704✔
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