# Java Vulnerability Examples and Fixes

> **Use this page when:** reviewing Java or Spring services, servlet-era code, XML-heavy integrations, or enterprise APIs that mix legacy libraries with modern platform expectations.

## How to read these examples

* **Vulnerable snippet** shows the unsafe habit.
* **Safer pattern** shows the direction you want in production code.
* **Why it matters** ties the defect to attacker value and business impact.
* **Review cue** is phrased so it can become a pull-request comment or checklist item.

## Example 1 — SQL injection with Statement

### Vulnerable snippet

```java
String email = request.getParameter("email");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(
    "SELECT id, role FROM users WHERE email = '" + email + "'"
);
```

### Safer pattern

```java
String email = request.getParameter("email");
PreparedStatement ps = conn.prepareStatement(
    "SELECT id, role FROM users WHERE email = ?"
);
ps.setString(1, email);
ResultSet rs = ps.executeQuery();
```

**Why it matters**

* Plain string concatenation puts attacker-controlled content into the SQL grammar itself.

**Business impact**

* Sensitive data exposure, account takeover via auth queries, and broader blast radius if DB roles are too wide.

**Review cue**

* Default to `PreparedStatement` or framework-level parameter binding; ban dynamic SQL for plain value insertion.

## Example 2 — XXE in XML parser configuration

### Vulnerable snippet

```java
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(inputStream);
```

### Safer pattern

```java
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(inputStream);
```

**Why it matters**

* Default XML parsing can resolve external entities and expose files, services, or network paths you never intended to trust.

**Business impact**

* File disclosure, SSRF, parser-based denial of service, or internal network reachability.

**Review cue**

* Every XML parser must be hardened deliberately; never assume safe defaults in older libraries or frameworks.

## Example 3 — Unsafe deserialization of untrusted data

### Vulnerable snippet

```java
byte[] bytes = Base64.getDecoder().decode(request.getParameter("state"));
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
Object state = ois.readObject();
```

### Safer pattern

```java
StateDto state = objectMapper.readValue(request.getParameter("state"), StateDto.class);
validateStateDto(state);
```

**Why it matters**

* Native Java deserialization has a long history of gadget-based exploitation and logic abuse when fed untrusted bytes.

**Business impact**

* Remote code execution, denial of service, and deep compromise of app servers or worker tiers.

**Review cue**

* Avoid native object deserialization for untrusted data; prefer constrained formats and explicit DTO validation.

## Example 4 — Path traversal in report download

### Vulnerable snippet

```java
String name = request.getParameter("name");
Path path = Paths.get("/srv/reports", name);
return Files.readString(path);
```

### Safer pattern

```java
String name = request.getParameter("name");
Path base = Paths.get("/srv/reports").toRealPath();
Path path = base.resolve(name).normalize();
if (!path.startsWith(base)) {
    throw new AccessDeniedException("invalid path");
}
return Files.readString(path);
```

**Why it matters**

* User-supplied file names can escape the intended directory unless the final normalized path is checked.

**Business impact**

* Disclosure of secrets, app config, source code, and operational documents.

**Review cue**

* Resolve, normalize, and verify `startsWith(base)` before touching the file system.

## Example 5 — Broken access control in controller or service layer

### Vulnerable snippet

```java
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
    return orderRepository.findById(id).orElseThrow();
}
```

### Safer pattern

```java
@GetMapping("/orders/{id}")
public Order getOrder(@AuthenticationPrincipal AppUser user,
                      @PathVariable Long id) {
    return orderRepository.findByIdAndOwnerUserId(id, user.getId())
        .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}
```

**Why it matters**

* Looking up records by ID alone turns every predictable identifier into a possible cross-user access path.

**Business impact**

* Cross-account data exposure, unauthorized order actions, and high-severity incident response burden.

**Review cue**

* The repository or service call should encode ownership or tenant scope, not just the controller path.

## Related pages

* [Spring / ASP.NET / Go Security Review Guide](https://github.com/D3One/Product-Security-Gitbook/blob/main/20-stack-specific-secure-engineering/spring-aspnet-and-go-security-review-guide.md)
* [API Authentication and Authorization](/architecture-api-crypto-and-identity/index/api-authentication-and-authorization.md)
* [SSRF, File Fetch, and Parser Abuse Review Guide](/application-security-and-secure-sdlc/index-1/ssrf-file-fetch-and-parser-abuse.md)

***

*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/application-security-and-secure-sdlc/index-4/java-vulnerability-examples-and-fixes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
