rack-libinjection 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +55 -0
  3. data/CHANGELOG.md +112 -0
  4. data/GET_STARTED.md +418 -0
  5. data/LICENSE-libinjection.txt +33 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +68 -0
  8. data/SECURITY.md +65 -0
  9. data/ext/libinjection/extconf.rb +113 -0
  10. data/ext/libinjection/libinjection_ext.c +1132 -0
  11. data/ext/libinjection/vendor/libinjection/.vendored +5 -0
  12. data/ext/libinjection/vendor/libinjection/COPYING +33 -0
  13. data/ext/libinjection/vendor/libinjection/MIGRATION.md +393 -0
  14. data/ext/libinjection/vendor/libinjection/README.md +251 -0
  15. data/ext/libinjection/vendor/libinjection/src/libinjection.h +70 -0
  16. data/ext/libinjection/vendor/libinjection/src/libinjection_error.h +26 -0
  17. data/ext/libinjection/vendor/libinjection/src/libinjection_html5.c +830 -0
  18. data/ext/libinjection/vendor/libinjection/src/libinjection_html5.h +56 -0
  19. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli.c +2342 -0
  20. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli.h +297 -0
  21. data/ext/libinjection/vendor/libinjection/src/libinjection_sqli_data.h +9651 -0
  22. data/ext/libinjection/vendor/libinjection/src/libinjection_xss.c +1203 -0
  23. data/ext/libinjection/vendor/libinjection/src/libinjection_xss.h +23 -0
  24. data/lib/libinjection/version.rb +6 -0
  25. data/lib/libinjection.rb +31 -0
  26. data/lib/rack/libinjection.rb +586 -0
  27. data/lib/rack-libinjection.rb +3 -0
  28. data/samples/README.md +67 -0
  29. data/samples/libinjection_detect_raw_hot_path.rb +161 -0
  30. data/samples/rack_all_surfaces_hot_path.rb +198 -0
  31. data/samples/rack_params_hot_path.rb +166 -0
  32. data/samples/rack_query_hot_path.rb +176 -0
  33. data/samples/results/.gitkeep +0 -0
  34. data/script/fuzz_smoke.rb +39 -0
  35. data/script/vendor_libs.rb +227 -0
  36. data/test/test_helper.rb +7 -0
  37. data/test/test_libinjection.rb +223 -0
  38. data/test/test_middleware.rb +404 -0
  39. metadata +148 -0
@@ -0,0 +1,5 @@
1
+ # rack-libinjection vendor manifest. Do not edit by hand. Regenerate with: ruby script/vendor_libs.rb
2
+ libinjection_version=4.0.0
3
+ libinjection_url=https://codeload.github.com/libinjection/libinjection/tar.gz/v4.0.0?dummy=/
4
+ libinjection_archive_sha256=a69d27e3d98608df89203c4e1c00c034fe0f8c723017e4088ab53ce3ff5a9129
5
+ libinjection_tree_sha256=de73d6fdaa9b51970142c74941031a058491d5c883bb1eca9faa8bf9f874703b
@@ -0,0 +1,33 @@
1
+ Copyright (c) 2012-2016, Nick Galbreath
2
+ Copyright (c) 2017-2024, libinjection Contributors
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are
7
+ met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in the
14
+ documentation and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ https://github.com/libinjection/libinjection
33
+ http://opensource.org/licenses/BSD-3-Clause
@@ -0,0 +1,393 @@
1
+ # Migration Guide: libinjection v3.x to v4.0
2
+
3
+ This guide helps you migrate from libinjection v3.x to v4.0, which introduces a breaking API change in error handling.
4
+
5
+ ## Overview of Changes
6
+
7
+ Version 4.0 introduces a new error handling model that **prevents process termination** on parser errors. Instead of calling `abort()` when encountering invalid parser states, the library now returns an error code that your application can handle gracefully.
8
+
9
+ ## What Changed
10
+
11
+ ### Return Type Change
12
+
13
+ All detection functions now return `injection_result_t` enum instead of `int`:
14
+
15
+ ```c
16
+ typedef enum injection_result_t {
17
+ LIBINJECTION_RESULT_FALSE = 0, // No injection detected (benign input)
18
+ LIBINJECTION_RESULT_TRUE = 1, // Injection detected
19
+ LIBINJECTION_RESULT_ERROR = -1 // Parser error (invalid state)
20
+ } injection_result_t;
21
+ ```
22
+
23
+ ### Affected Functions
24
+
25
+ - `libinjection_xss()`
26
+ - `libinjection_sqli()`
27
+ - `libinjection_is_xss()`
28
+ - `libinjection_h5_next()`
29
+
30
+ ### New Header File
31
+
32
+ Include the new error header:
33
+ ```c
34
+ #include "libinjection_error.h" // New in v4.0
35
+ ```
36
+
37
+ ## Migration Strategies
38
+
39
+ ### Strategy 1: Full Migration (Recommended)
40
+
41
+ Update your code to explicitly check all three return values:
42
+
43
+ **Before (v3.x):**
44
+ ```c
45
+ #include "libinjection.h"
46
+ #include "libinjection_sqli.h"
47
+
48
+ int check_input(const char *input) {
49
+ struct libinjection_sqli_state state;
50
+ char fingerprint[8];
51
+ int result;
52
+
53
+ libinjection_sqli_init(&state, input, strlen(input), FLAG_NONE);
54
+ result = libinjection_is_sqli(&state);
55
+
56
+ if (result) {
57
+ log("SQLi detected: %s", state.fingerprint);
58
+ return 1; // Block request
59
+ }
60
+
61
+ return 0; // Allow request
62
+ }
63
+ ```
64
+
65
+ **After (v4.0):**
66
+ ```c
67
+ #include "libinjection.h"
68
+ #include "libinjection_error.h"
69
+ #include "libinjection_sqli.h"
70
+
71
+ int check_input(const char *input) {
72
+ struct libinjection_sqli_state state;
73
+ char fingerprint[8];
74
+ injection_result_t result;
75
+
76
+ libinjection_sqli_init(&state, input, strlen(input), FLAG_NONE);
77
+ result = libinjection_is_sqli(&state);
78
+
79
+ if (result == LIBINJECTION_RESULT_ERROR) {
80
+ log_error("Parser error - treating as suspicious");
81
+ return 1; // Block on error (fail-safe)
82
+ } else if (result == LIBINJECTION_RESULT_TRUE) {
83
+ log("SQLi detected: %s", state.fingerprint);
84
+ return 1; // Block request
85
+ }
86
+
87
+ return 0; // Allow request
88
+ }
89
+ ```
90
+
91
+ ### Strategy 2: Minimal Migration (Quick Fix)
92
+
93
+ For quick migration with minimal code changes, treat errors as detections:
94
+
95
+ ```c
96
+ injection_result_t result;
97
+
98
+ result = libinjection_sqli(input, len, fingerprint);
99
+
100
+ // Treat error as detection (fail-safe approach)
101
+ if (result == LIBINJECTION_RESULT_TRUE || result == LIBINJECTION_RESULT_ERROR) {
102
+ // Block request
103
+ return 1;
104
+ }
105
+
106
+ return 0; // Allow only if LIBINJECTION_RESULT_FALSE
107
+ ```
108
+
109
+ ### Strategy 3: Backward Compatible Check
110
+
111
+ If you need to maintain compatibility during transition:
112
+
113
+ ```c
114
+ injection_result_t result;
115
+
116
+ result = libinjection_xss(input, len);
117
+
118
+ // Old style: simple truthy check still works for detection
119
+ // but won't distinguish error from injection
120
+ if (result) {
121
+ // Handles both LIBINJECTION_RESULT_TRUE and LIBINJECTION_RESULT_ERROR (since -1 is truthy)
122
+ return 1;
123
+ }
124
+
125
+ return 0;
126
+ ```
127
+
128
+ **Warning:** This approach treats errors as benign input when checking `!result`, which is unsafe.
129
+
130
+ ## Migration by Use Case
131
+
132
+ ### Web Application Firewall (WAF)
133
+
134
+ Recommended approach: **Fail-safe** - block on both detection and error.
135
+
136
+ ```c
137
+ injection_result_t sqli_result = libinjection_sqli(input, len, fp);
138
+ injection_result_t xss_result = libinjection_xss(input, len);
139
+
140
+ if (sqli_result == LIBINJECTION_RESULT_TRUE || sqli_result == LIBINJECTION_RESULT_ERROR ||
141
+ xss_result == LIBINJECTION_RESULT_TRUE || xss_result == LIBINJECTION_RESULT_ERROR) {
142
+
143
+ log_security_event(input, sqli_result, xss_result);
144
+ return HTTP_403_FORBIDDEN;
145
+ }
146
+
147
+ return HTTP_200_OK;
148
+ ```
149
+
150
+ ### Logging/Monitoring System
151
+
152
+ Recommended approach: **Distinguish** between detection and errors.
153
+
154
+ ```c
155
+ injection_result_t result = libinjection_xss(input, len);
156
+
157
+ switch (result) {
158
+ case LIBINJECTION_RESULT_TRUE:
159
+ log_metric("xss.detected", 1);
160
+ alert_security_team(input);
161
+ break;
162
+
163
+ case LIBINJECTION_RESULT_ERROR:
164
+ log_metric("xss.parser_error", 1);
165
+ log_error("Parser error on input: %.*s", (int)len, input);
166
+ // Continue processing - may be benign malformed input
167
+ break;
168
+
169
+ case LIBINJECTION_RESULT_FALSE:
170
+ log_metric("xss.clean", 1);
171
+ break;
172
+ }
173
+ ```
174
+
175
+ ### Embedded System
176
+
177
+ Recommended approach: **Graceful degradation** with error recovery.
178
+
179
+ ```c
180
+ injection_result_t result = libinjection_sqli(input, len, fp);
181
+
182
+ if (result == LIBINJECTION_RESULT_ERROR) {
183
+ // Log error but don't block - keep system running
184
+ error_count++;
185
+
186
+ if (error_count > ERROR_THRESHOLD) {
187
+ // Too many errors - may indicate attack or bug
188
+ enter_safe_mode();
189
+ }
190
+
191
+ return ALLOW; // Degrade gracefully
192
+ }
193
+
194
+ return (result == LIBINJECTION_RESULT_TRUE) ? BLOCK : ALLOW;
195
+ ```
196
+
197
+ ## Testing Your Migration
198
+
199
+ ### 1. Compile-time Checks
200
+
201
+ After migration, your code should compile with the new type:
202
+
203
+ ```c
204
+ injection_result_t result; // Not 'int'
205
+ result = libinjection_xss(input, len);
206
+ ```
207
+
208
+ ### 2. Runtime Testing
209
+
210
+ Test with these scenarios:
211
+
212
+ ```c
213
+ // Normal detection - should return LIBINJECTION_RESULT_TRUE
214
+ libinjection_xss("<script>alert(1)</script>", 28);
215
+
216
+ // Benign input - should return LIBINJECTION_RESULT_FALSE
217
+ libinjection_xss("hello world", 11);
218
+
219
+ // Edge cases that might trigger LIBINJECTION_RESULT_ERROR
220
+ libinjection_xss("", 0); // Empty string
221
+ // Very long inputs, deeply nested structures, etc.
222
+ ```
223
+
224
+ ### 3. Error Handling Test
225
+
226
+ Verify your error handling:
227
+
228
+ ```c
229
+ injection_result_t result = libinjection_xss(test_input, len);
230
+
231
+ assert(result == LIBINJECTION_RESULT_FALSE ||
232
+ result == LIBINJECTION_RESULT_TRUE ||
233
+ result == LIBINJECTION_RESULT_ERROR); // Only valid values
234
+
235
+ // Ensure you handle all three cases
236
+ switch (result) {
237
+ case LIBINJECTION_RESULT_FALSE: /* ... */ break;
238
+ case LIBINJECTION_RESULT_TRUE: /* ... */ break;
239
+ case LIBINJECTION_RESULT_ERROR: /* ... */ break;
240
+ }
241
+ ```
242
+
243
+ ## Common Pitfalls
244
+
245
+ ### ❌ Don't: Ignore errors
246
+
247
+ ```c
248
+ // WRONG - error becomes benign
249
+ if (result == LIBINJECTION_RESULT_TRUE) {
250
+ block();
251
+ }
252
+ // LIBINJECTION_RESULT_ERROR falls through as allowed!
253
+ ```
254
+
255
+ ### ✅ Do: Explicitly handle errors
256
+
257
+ ```c
258
+ // CORRECT
259
+ if (result == LIBINJECTION_RESULT_ERROR) {
260
+ handle_error();
261
+ } else if (result == LIBINJECTION_RESULT_TRUE) {
262
+ block();
263
+ }
264
+ ```
265
+
266
+ ### ❌ Don't: Use simple equality for "not detected"
267
+
268
+ ```c
269
+ // WRONG - error will pass this check
270
+ if (result == 0) { // Only catches LIBINJECTION_RESULT_FALSE
271
+ allow();
272
+ }
273
+ ```
274
+
275
+ ### ✅ Do: Use enum constants
276
+
277
+ ```c
278
+ // CORRECT
279
+ if (result == LIBINJECTION_RESULT_FALSE) {
280
+ allow();
281
+ }
282
+ ```
283
+
284
+ ## Language Bindings
285
+
286
+ ### Python
287
+
288
+ The enum values are accessible as integers in the Python binding:
289
+
290
+ ```python
291
+ import libinjection
292
+
293
+ result = libinjection.xss(test_input)
294
+
295
+ if result == -1: # LIBINJECTION_RESULT_ERROR
296
+ handle_error()
297
+ elif result == 1: # LIBINJECTION_RESULT_TRUE
298
+ block_request()
299
+ else: # result == 0, LIBINJECTION_RESULT_FALSE
300
+ allow_request()
301
+ ```
302
+
303
+ ### PHP
304
+
305
+ ```php
306
+ <?php
307
+ $result = libinjection_xss($input);
308
+
309
+ if ($result === -1) { // LIBINJECTION_RESULT_ERROR
310
+ handle_error();
311
+ } elseif ($result === 1) { // LIBINJECTION_RESULT_TRUE
312
+ block_request();
313
+ } else { // $result === 0, LIBINJECTION_RESULT_FALSE
314
+ allow_request();
315
+ }
316
+ ```
317
+
318
+ ### Lua
319
+
320
+ ```lua
321
+ local libinjection = require "libinjection"
322
+
323
+ local result = libinjection.xss(input)
324
+
325
+ if result == -1 then -- LIBINJECTION_RESULT_ERROR
326
+ handle_error()
327
+ elseif result == 1 then -- LIBINJECTION_RESULT_TRUE
328
+ block_request()
329
+ else -- result == 0, LIBINJECTION_RESULT_FALSE
330
+ allow_request()
331
+ end
332
+ ```
333
+
334
+ ## Why This Change?
335
+
336
+ ### The Problem with v3.x
337
+
338
+ In v3.x, when the parser encountered an invalid state (e.g., cursor position exceeding string length), it would call `assert()` or `abort()`, immediately terminating your entire process:
339
+
340
+ ```c
341
+ // v3.x behavior (REMOVED in v4.0)
342
+ assert(hs->len >= hs->pos); // CRASH if violated
343
+ ```
344
+
345
+ This was problematic for:
346
+ - **Web servers**: Malicious input could crash the server
347
+ - **Embedded systems**: Required high availability, no crashes
348
+ - **Production services**: Needed graceful degradation
349
+
350
+ ### The Solution in v4.0
351
+
352
+ Parser errors now return `LIBINJECTION_RESULT_ERROR` instead of terminating:
353
+
354
+ ```c
355
+ // v4.0 behavior
356
+ if (hs->len < hs->pos) {
357
+ return LIBINJECTION_RESULT_ERROR; // Graceful error return
358
+ }
359
+ ```
360
+
361
+ Your application can now:
362
+ - Log the error for debugging
363
+ - Continue running other requests
364
+ - Implement custom error policies
365
+ - Monitor error rates
366
+
367
+ ## Need Help?
368
+
369
+ - **Issues**: https://github.com/libinjection/libinjection/issues
370
+ - **Pull Request**: https://github.com/libinjection/libinjection/pull/65
371
+ - **Documentation**: See README.md for updated examples
372
+
373
+ ## Checklist
374
+
375
+ Use this checklist to verify your migration:
376
+
377
+ - [ ] Updated all `int` return types to `injection_result_t`
378
+ - [ ] Added `#include "libinjection_error.h"`
379
+ - [ ] Explicitly handle `LIBINJECTION_RESULT_ERROR` in all code paths
380
+ - [ ] Updated language binding code (if applicable)
381
+ - [ ] Added tests for error conditions
382
+ - [ ] Verified fail-safe behavior (block on error in security contexts)
383
+ - [ ] Updated logging/monitoring to track error rates
384
+ - [ ] Tested with edge cases (empty strings, very long inputs, etc.)
385
+ - [ ] Reviewed all `if (result)` checks for proper error handling
386
+ - [ ] Updated internal documentation and team guidelines
387
+
388
+ ---
389
+
390
+ **Version**: 4.0.0
391
+ **Last Updated**: 2025
392
+ **Status**: Current
393
+
@@ -0,0 +1,251 @@
1
+
2
+ <img src="https://raw.githubusercontent.com/libinjection/libinjection/main/misc/libinjection.svg" width="70%">
3
+
4
+ ![CI](https://github.com/libinjection/libinjection/workflows/CI/badge.svg)
5
+ [![license](https://img.shields.io/badge/license-BSD_3--Clause-blue.svg?style=flat)](https://raw.githubusercontent.com/libinjection/libinjection/main/COPYING)
6
+
7
+
8
+ SQL / SQLI tokenizer parser analyzer. For
9
+
10
+ * C and C++
11
+ * [PHP](https://libinjection.client9.com/doc-sqli-php)
12
+ * [Python](https://libinjection.client9.com/doc-sqli-python)
13
+ * [Lua](/lua)
14
+ * [Java](https://github.com/jeonglee/Libinjection) (external port)
15
+ * [LuaJIT/FFI](https://github.com/p0pr0ck5/lua-ffi-libinjection) (external port)
16
+
17
+ See [https://www.client9.com/](https://www.client9.com/)
18
+ for details and presentations.
19
+
20
+ Simple example:
21
+
22
+ ```c
23
+ #include <stdio.h>
24
+ #include <strings.h>
25
+ #include <errno.h>
26
+ #include "libinjection.h"
27
+ #include "libinjection_sqli.h"
28
+
29
+ int main(int argc, const char* argv[])
30
+ {
31
+ struct libinjection_sqli_state state;
32
+ injection_result_t result;
33
+
34
+ const char* input = argv[1];
35
+ size_t slen = strlen(input);
36
+
37
+ /* in real-world, you would url-decode the input, etc */
38
+
39
+ libinjection_sqli_init(&state, input, slen, FLAG_NONE);
40
+ result = libinjection_is_sqli(&state);
41
+
42
+ if (result == LIBINJECTION_RESULT_ERROR) {
43
+ fprintf(stderr, "error: parser encountered an error\n");
44
+ return 2;
45
+ } else if (result == LIBINJECTION_RESULT_TRUE) {
46
+ fprintf(stderr, "sqli detected with fingerprint of '%s'\n", state.fingerprint);
47
+ return 1;
48
+ }
49
+
50
+ /* LIBINJECTION_RESULT_FALSE - no SQLi detected */
51
+ return 0;
52
+ }
53
+ ```
54
+
55
+ ```
56
+ $ gcc -Wall -Wextra examples.c libinjection_sqli.c
57
+ $ ./a.out "-1' and 1=1 union/* foo */select load_file('/etc/passwd')--"
58
+ sqli detected with fingerprint of 's&1UE'
59
+ ```
60
+
61
+ More advanced samples:
62
+
63
+ * [sqli_cli.c](/src/sqli_cli.c)
64
+ * [reader.c](/src/reader.c)
65
+ * [fptool](/src/fptool.c)
66
+
67
+ VERSION INFORMATION
68
+ ===================
69
+
70
+ See [CHANGELOG](CHANGELOG.md) for details.
71
+
72
+ Versions are listed as "major.minor.point"
73
+
74
+ Major are significant changes to the API and/or fingerprint format.
75
+ Applications will need recompiling and/or refactoring.
76
+
77
+ Minor are C code changes. These may include
78
+ * logical change to detect or suppress
79
+ * optimization changes
80
+ * code refactoring
81
+
82
+ Point releases are purely data changes. These may be safely applied.
83
+
84
+ ERROR HANDLING
85
+ ==============
86
+
87
+ As of version 4.0.0, libinjection uses an `injection_result_t` enum for return values instead of `int`:
88
+
89
+ ```c
90
+ typedef enum injection_result_t {
91
+ LIBINJECTION_RESULT_FALSE = 0, // No injection detected (benign input)
92
+ LIBINJECTION_RESULT_TRUE = 1, // Injection detected
93
+ LIBINJECTION_RESULT_ERROR = -1 // Parser error (invalid state)
94
+ } injection_result_t;
95
+ ```
96
+
97
+ **Important:** Prior to v4.0.0, libinjection would call `abort()` and terminate the process when encountering parser errors. Now it returns `LIBINJECTION_RESULT_ERROR` instead, allowing your application to handle errors gracefully.
98
+
99
+ **Backward Compatibility:** The enum values `LIBINJECTION_RESULT_FALSE` (0) and `LIBINJECTION_RESULT_TRUE` (1) maintain backward compatibility with code that checks for true/false values. However, applications should be updated to handle `LIBINJECTION_RESULT_ERROR` (-1) to prevent treating parser errors as benign input.
100
+
101
+ **Migration:** See [MIGRATION.md](MIGRATION.md) for guidance on updating existing code.
102
+
103
+ QUALITY AND DIAGNOSITICS
104
+ ========================
105
+
106
+ The continuous integration results at GitHub tests the following:
107
+
108
+ - [x] build and unit-tests under GCC
109
+ - [x] build and unit-tests under Clang
110
+ - [x] static analysis using [clang static analyzer](http://clang-analyzer.llvm.org)
111
+ - [x] static analysis using [cppcheck](https://github.com/danmar/cppcheck)
112
+ - [x] checks for memory errors using [valgrind](http://valgrind.org/)
113
+
114
+ LICENSE
115
+ =============
116
+
117
+ Copyright (c) 2012-2016, Nick Galbreath
118
+ Copyright (c) 2017-2024, libinjection Contributors
119
+
120
+ Licensed under the standard [BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) open source
121
+ license. See [COPYING](/COPYING) for details.
122
+
123
+ ## BUILD TARGETS
124
+
125
+ Some of the previous help runners have been merged into the Makefile. E.g.:
126
+
127
+ * run-clang-asan.sh -> `make clan-asan`
128
+ * make-ci.sh -> `make ci`
129
+
130
+ ### Building and Installing Libraries
131
+
132
+ The autotools build system uses **libtool**, which places built libraries in the `src/.libs/` directory (not directly in `src/` like older versions).
133
+
134
+ **Basic build:**
135
+ ```bash
136
+ ./autogen.sh
137
+ ./configure
138
+ make
139
+
140
+ # Built libraries are located at:
141
+ # - src/.libs/libinjection.a (static library)
142
+ # - src/.libs/libinjection.so (Linux shared) or src/.libs/libinjection.dylib (macOS shared)
143
+ ```
144
+
145
+ **Building static libraries:**
146
+ ```bash
147
+ ./configure --enable-static
148
+ make
149
+ find . -name "*.a"
150
+ # Output: ./src/.libs/libinjection.a
151
+ ```
152
+
153
+ **Installing to a specific location:**
154
+ ```bash
155
+ ./configure --prefix=/path/to/install
156
+ make
157
+ make install
158
+
159
+ # This installs:
160
+ # - Headers: /path/to/install/include/libinjection*.h
161
+ # - Libraries: /path/to/install/lib/libinjection.{a,so,dylib}
162
+ # - pkg-config: /path/to/install/lib/pkgconfig/libinjection.pc
163
+ ```
164
+
165
+ **Linking against libinjection:**
166
+
167
+ Option 1 - Link against installed library (via pkg-config):
168
+ ```bash
169
+ ./configure --prefix=/usr/local
170
+ make install
171
+ gcc myapp.c $(pkg-config --cflags --libs libinjection)
172
+ ```
173
+
174
+ Option 2 - Link against build tree without installing:
175
+ ```bash
176
+ gcc myapp.c -I/path/to/libinjection/src -L/path/to/libinjection/src/.libs -linjection
177
+ ```
178
+
179
+ Option 3 - Static linking from build tree:
180
+ ```bash
181
+ gcc myapp.c -I/path/to/libinjection/src /path/to/libinjection/src/.libs/libinjection.a
182
+ ```
183
+
184
+ ### Migrating from Older Versions (client9/libinjection)
185
+
186
+ If you're upgrading from the old Makefile-based build system where `libinjection.a` was in `src/`, note that libraries are now in `src/.libs/`.
187
+
188
+ **Update your build scripts:**
189
+
190
+ For Makefiles:
191
+ ```makefile
192
+ LIBINJECTION_DIR = ../libinjection
193
+ CFLAGS += -I$(LIBINJECTION_DIR)/src
194
+ LDFLAGS += -L$(LIBINJECTION_DIR)/src/.libs -linjection
195
+ ```
196
+
197
+ For CMake:
198
+ ```cmake
199
+ target_include_directories(myapp PRIVATE ../libinjection/src)
200
+ target_link_directories(myapp PRIVATE ../libinjection/src/.libs)
201
+ target_link_libraries(myapp injection)
202
+ ```
203
+
204
+ If your build system requires libraries in a specific location:
205
+ ```bash
206
+ ./configure && make
207
+ cp src/.libs/libinjection.a /desired/location/
208
+ ```
209
+
210
+ For more information, see:
211
+ - GNU Libtool documentation: https://www.gnu.org/software/libtool/manual/html_node/Linking-libraries.html
212
+ - GitHub issue #54
213
+
214
+ ### Static Analysis
215
+
216
+ If you run `make cppcheck` you will see this warning printed:
217
+ ```
218
+ nofile:0 information missingIncludeSystem Cppcheck cannot find all the include files (use --check-config for details)
219
+ ```
220
+ You can safely ignore it as it is just saying that standard include files are being ignored (which is the recommended option):
221
+ ```
222
+ example1.c:1:0: information: Include file: <stdio.h> not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]
223
+ ```
224
+
225
+ EMBEDDING
226
+ =============
227
+
228
+ The [src](/src)
229
+ directory contains everything, but you only need to copy the following
230
+ into your source tree:
231
+
232
+ * [src/libinjection.h](/src/libinjection.h)
233
+ * [src/libinjection_error.h](/src/libinjection_error.h)
234
+ * [src/libinjection_sqli.h](/src/libinjection_sqli.h)
235
+ * [src/libinjection_sqli.c](/src/libinjection_sqli.c)
236
+ * [src/libinjection_sqli_data.h](/src/libinjection_sqli_data.h)
237
+ * [COPYING](/COPYING)
238
+
239
+ For XSS detection, also copy:
240
+
241
+ * [src/libinjection_xss.h](/src/libinjection_xss.h)
242
+ * [src/libinjection_xss.c](/src/libinjection_xss.c)
243
+ * [src/libinjection_html5.h](/src/libinjection_html5.h)
244
+ * [src/libinjection_html5.c](/src/libinjection_html5.c)
245
+
246
+ The source includes a default version string (`"4.0.0"`).
247
+ You can override this at build time, for example by defining `LIBINJECTION_VERSION`:
248
+
249
+ ```
250
+ CFLAGS="-DLIBINJECTION_VERSION=\"4.0.0-custom\""
251
+ ```