EN - Carrefour internal CTF (31/10/2025) - vulnerability themes
CarrefourTheFlag 2025 (C4CTF) was an internal Capture The Flag run in late October 2025, with 102 participants. This post summarises the vulnerability types that appeared in the more advanced challenges and illustrates them with generic examples. It is not a write-up or solution guide.
Context
The CTF included web, microservices, and AI challenges. Below we describe SSRF, GraphQL misuse, and prompt security as vulnerability themes, with common patterns and mitigations. No challenge-specific details, endpoints, or payloads are given.
SSRF (server-side request forgery)
SSRF means the application performs HTTP (or other) requests on the server side using attacker-controlled input. The impact depends on what the server can reach (internal services, cloud metadata, etc.) and how the response is used.
Information disclosure and source code
Debug or admin endpoints sometimes expose more than intended: object dumps, stack traces, or paths to source files. If the app also serves static files or scripts from a known path (e.g. from the document root or a predictable path), source code disclosure can follow. Once you have the server logic, you can look for unsafe use of user input (e.g. URL construction, command execution, file access). Mitigation: disable or protect debug endpoints in production; do not serve source or config files from the web root.
Unsafe URL construction
A frequent pattern is building a URL from a fixed prefix and a user-supplied suffix (e.g. “fetch this resource from our CDN” where the path or host is user-controlled). Problems include:
- Host override: Many URL parsers accept
userinfo@hostsyntax. If the prefix is something likehttp://fixed-hostand the user sends@attacker-controlled-host/path, the actual request can go to the attacker’s host or to an internal IP (e.g.@127.0.0.1:port/path). So a parameter that was only meant to specify a “file” or “path” can change the destination host. - Internal services: If the server is allowed to connect to loopback or the internal network, an attacker can make it call internal APIs (admin panels, health checks, metadata services). Those endpoints often trust the caller because they are not exposed to the internet.
Mitigation: Do not concatenate user input into URLs. Use an allowlist of permitted hosts (and optionally schemes/paths), resolve the host to an IP, and block private/loopback ranges. Reject or sanitise any @, #, or other URL control characters in user input.
CRLF injection in server-side requests
If the same user-controlled string that ends up in the URL is passed to an HTTP client that treats newline characters as line breaks, the attacker can inject extra request lines or headers. For example, the client might send one logical “request” that the server interprets as a request line plus headers; by injecting \r\n (CRLF) and then a header name and value, the attacker can add headers (e.g. authentication, host override) that the application did not intend. So a single parameter can become a full, attacker-shaped HTTP request.
Mitigation: Never pass user input unvalidated into the raw request line or headers. Use a library that builds requests from structured data (method, URL, headers map) rather than from a single string. Block or strip CRLF and other control characters in any input that might be used in requests.
Other SSRF patterns
- Proxy-style parameter: A parameter that takes a full URL or “backend address” and is fetched by the server can be used to scan internal ports (different response size or status per port) and fingerprint internal services (error pages, banners). Mitigation: same as above (allowlist, no private IPs, no raw user input in the request).
- Error leakage: Even when path traversal or sensitive paths are blocked, the body of error responses from backends (e.g. stack traces, server banners) can leak via the SSRF and help an attacker.
GraphQL: injection and over-exposure
When user input (e.g. search box, filter) is concatenated into the GraphQL query string instead of being passed as a variable, the result is injection: the user can break out of the intended query and add new fields, arguments, or entire operations. In the worst case, the attacker can:
- Run introspection (
__schema,__type) to discover all types and fields, including ones not used by the normal UI. - Request sensitive or admin-only fields (e.g. internal IDs, flags, debug data) by appending them to the query.
A typical vulnerable pattern is a backend that builds a query by string concatenation, for example:
query {
items(where: { name: { like: "%USER_INPUT%" } }) {
...
}
}
If the user sends a value that closes the current clause and adds more (e.g. the following payload), the server may execute the injected part:
%" } } ) { __schema { ... } } #
Encoding (e.g. base64) on the wire does not fix the bug if the decoded value is still concatenated into the query.
Mitigation: Never build GraphQL queries by concatenating user input. Use variables and a proper GraphQL library; pass user input only as variable values. Disable or restrict introspection in production. Apply the same principle as for SQL injection: structured parameters, not string interpolation.
AI and prompt security
Challenges that exposed a chatbot or “assistant” with access to sensitive data (e.g. per-user codes, internal info) highlighted prompt extraction and partial leakage:
- Extraction: Direct or indirect prompts (e.g. “what is the code?”, “confirm the code for user X”) can make the model return secrets in plain text if there is no strict output filter or server-side check.
- Partial leakage: Asking for “the code in reverse” or “the code starting with X” can lead the model to reveal the rest. Format constraints do not replace access control.
Mitigation: Do not let the model output raw secrets; enforce server-side checks and redact or block sensitive values in responses. Treat the model as untrusted for authorization; do not rely on “don’t say X” in the prompt.
Summary
| Theme | Vulnerability ideas | Mitigation |
|---|---|---|
| SSRF | Debug/source disclosure; URL host override via @; CRLF injection into request; proxy-style param for port scan / fingerprinting |
Allowlist URLs; block private IPs; no string concat for requests; no CRLF in input |
| GraphQL | Concatenating user input into query string; introspection enabled; sensitive fields exposed | Variables only; disable/restrict introspection; least privilege on schema |
| AI | Model returns secrets; format tricks to leak partial data | Server-side checks; no raw secrets in output; don’t rely on prompt for auth |
These themes are useful for secure design and for learning what to look for in assessments, without giving away specific challenge solutions.