# Input Validation and Output Encoding — DevSecOps

Source: https://www.skillbyai.com/en/devsecops/dso-input-output

> Validate input with allow-lists and encode output for its context to prevent cross-site scripting.

## Validate in, encode out

Two complementary habits stop a large share of web bugs. **Input validation** checks that incoming data has the expected type, length, format and range, preferably with an **allow-list** (what is permitted) rather than a deny-list (what is forbidden), because attackers are creative at finding forms you did not think to deny. Validate on the server; client-side checks are only a convenience. **Output encoding** transforms data when you place it into a specific context so it cannot break out: HTML-encode text placed into a page, use URL encoding in query strings, JSON-encode for scripts. **Cross-site scripting (XSS)** happens when user text reaches an HTML page without encoding and the browser runs it as script. Modern template engines such as Jinja2, React's JSX and Angular's templates encode by default; bugs appear when developers bypass that with raw-HTML features. A **Content-Security-Policy** header adds a second layer by restricting which scripts may run.

## Encoding for the HTML context

Python's standard library encodes the five HTML-special characters.

```python
import html, re

comment = '<script>alert("hi")</script>'
print(html.escape(comment))

PINCODE = re.compile(r"[1-9][0-9]{5}")  # allow-list: Indian PIN format
for value in ["560001", "56A001", "0123456"]:
    print(value, bool(PINCODE.fullmatch(value)))
```

Output:

```
&lt;script&gt;alert(&quot;hi&quot;)&lt;/script&gt;
560001 True
56A001 False
0123456 False
```

## Raw-HTML escape hatches

Search your code for `innerHTML`, React's `dangerouslySetInnerHTML`, Angular's `bypassSecurityTrust*` and Jinja's `|safe`. Each one turns off automatic encoding and deserves a review comment.

**Quiz:** Which approach to input validation is generally stronger?

- [ ] A deny-list of known bad strings
- [ ] Client-side JavaScript checks only
- [ ] No validation, relying only on a firewall
- [x] An allow-list describing exactly what valid input looks like

*Answer:* An allow-list describing exactly what valid input looks like. Allow-lists fail safe: anything not explicitly valid is rejected, so unknown attack forms are blocked too.
