secure_output 0.1.1

Context-aware output encoding and URI sanitization for safer application responses.
Documentation

secure_output

crates.io docs.rs License: MIT OR Apache-2.0

Context-aware output encoding for every place an application emits data — HTML, JSON, URL, JS strings, CSS, XML, LDAP, shell (OWASP C4). Part of the SunLit Security Libraries workspace.

When to reach for this crate

  • You're rendering server-side HTML and need an injection-safe encoder that's zero-copy when input is already safe.
  • You're embedding user input into JSON inside a <script> tag (the classic </script> injection pitfall).
  • You're building LDAP filters or shell argument strings and want explicit RFC-compliant encoders.
  • You need to sanitize URI schemes so <a href> and <img src> can't host javascript: or data: attacks.

All encoders implement an open OutputEncoder trait so callers pick by context, not by guesswork.

Install

[dependencies]
secure_output = "0.1"

Quick example

use secure_output::{HtmlEncoder, JsonEncoder, UrlEncoder, sanitize_uri_scheme};
use secure_output::encode::OutputEncoder;
use std::borrow::Cow;

// HTML body or attribute encoding — zero-copy for safe strings.
let html: Cow<str> = HtmlEncoder.encode("<b>hi</b>");
assert_eq!(html, "&lt;b&gt;hi&lt;/b&gt;");

// JSON encoding that also escapes </script> for inline-script embedding.
let json: Cow<str> = JsonEncoder.encode(r#"</script><script>alert(1)</script>"#);
assert!(!json.contains("</script>"));

// URL percent-encoding per RFC 3986.
let url: Cow<str> = UrlEncoder.encode("hello world & friends");
assert_eq!(url, "hello%20world%20%26%20friends");

// Block dangerous URI schemes before emitting an href/src.
let safe = sanitize_uri_scheme("javascript:alert(1)");
assert!(safe.is_err()); // returns DangerousUriScheme

What's inside

Type Encodes for
HtmlEncoder HTML body and attribute context (zero-copy when safe).
JsonEncoder JSON output, including </script> defense for inline-script embedding.
UrlEncoder RFC 3986 percent-encoding.
JsStringEncoder JavaScript string-literal context.
CssEncoder CSS context via Unicode escape.
XmlEncoder XML text and attribute context.
ldap::LdapDnEncoder LDAP Distinguished Name (RFC 4514).
ldap::LdapFilterEncoder LDAP search filter (RFC 4515).
shell::ShellEncoder POSIX shell argument quoting.
sanitize_uri_scheme Returns DangerousUriScheme for javascript:, data:, etc.

Compatibility

  • MSRV: 1.78
  • #![forbid(unsafe_code)], #![deny(missing_docs)]
  • Zero allocations on the safe-string fast path (returns Cow::Borrowed)
  • Pure Rust, no system dependencies

Status

Alpha.

Related crates

Part of the SunLit Security Libraries workspace:

Crate Purpose
security_core Shared types, identity, classification, severity, redaction.
security_events Security logging and tamper-evident audit chain.
secure_errors Three-layer error model with redaction-safe public errors.
secure_data Secrets, envelope encryption, Argon2id, FIPS, mobile storage.
secure_network TLS policy, SPKI pinning, mTLS, cleartext detection.
secure_device_trust Native-client device trust and session certificates.
secure_resilience RASP and environment-detection policy.
secure_privacy PII classification, consent, retention, pseudonymization.
secure_boundary Input validation, security headers, boundary protections.
secure_identity JWT/OIDC, MFA, sessions, biometric step-up.
secure_authz Typed deny-by-default authorization with device-trust predicates.

Getting help

  • Questions, ideas, design discussions — open a GitHub Discussion.
  • Bug reports — use the bug-report template in GitHub Issues.
  • Security issues — please do not open a public issue. See SECURITY.md for the responsible-disclosure process.

Contributing

Contributions are welcome. Please read CONTRIBUTING.md and the Code of Conduct before opening a PR.

License

Dual-licensed under MIT or Apache-2.0 at your option.