#security-policy #security #csp #html-parser #http #validation

content-security-policy

Will parse and validate Content-Security-Policy level 3

11 unstable releases

0.5.2 Jul 29, 2024
0.5.1 May 22, 2023
0.5.0 Feb 25, 2023
0.4.2 Jul 8, 2020
0.0.0 Oct 2, 2017

#1241 in Network programming

Download history 3574/week @ 2024-08-14 2329/week @ 2024-08-21 3132/week @ 2024-08-28 2953/week @ 2024-09-04 2678/week @ 2024-09-11 1477/week @ 2024-09-18 2040/week @ 2024-09-25 2857/week @ 2024-10-02 2996/week @ 2024-10-09 3051/week @ 2024-10-16 2781/week @ 2024-10-23 2879/week @ 2024-10-30 2393/week @ 2024-11-06 2032/week @ 2024-11-13 2623/week @ 2024-11-20 1639/week @ 2024-11-27

9,185 downloads per month
Used in 2 crates (via stylo_malloc_size_of)

MIT/Apache

78KB
1.5K SLoC

Parse and validate Web Content-Security-Policy level 3

Crates.IO Requires rustc 1.70.0

This function parses a CSP string into a data structure, and provides a bunch of functions you can call on it (basically all of the "hooks" defined in the CSP standard). It directly uses the url crate, but it's intentionally agnostic to your HTML parser and your networking stack, so there are a few things it doesn't do:

  • While this library does directly use rust-url, it is intentionally not entangled with any particular networking stack, HTML parser, or DOM implementation.
  • Rather than directly adding events to the event loop, like the spec says, it returns a Vec<> of objects that the library's users should push to the event loop. Just iterate over the vec, convert to your internal event representation, and push them to the event loop after calling the rust-content-security-policy function. Since the CSP specification never spins the event loop in the middle of any of its algorithms, that will be spec compliant anyway.
  • Simple algorithms that don't operate on any part of the parsed CSP data structures, like is element nonceable, probably won't ever be implemented by this library. It would take as much effort for a user to convert from the HTML parser's data structure into whatever rust-content-security-policy would accept as it would take for them to just implement the algorithm themselves.

Installation

To use content-security-policy, add it to your project's Cargo.toml file:

[dependencies]
content-security-policy = "0.5.2"

Example

extern crate content_security_policy;
use content_security_policy::*;
fn main() {
    let csp_list = CspList::parse("script-src *.notriddle.com", PolicySource::Header, PolicyDisposition::Enforce);
    let (check_result, _) = csp_list.should_request_be_blocked(&Request {
        url: Url::parse("https://www.notriddle.com/script.js").unwrap(),
        origin: Origin::Tuple("https".to_string(), url::Host::Domain("notriddle.com".to_owned()), 443),
        redirect_count: 0,
        destination: Destination::Script,
        initiator: Initiator::None,
        nonce: String::new(),
        integrity_metadata: String::new(),
        parser_metadata: ParserMetadata::None,
    });
    assert_eq!(check_result, CheckResult::Allowed);
    let (check_result, _) = csp_list.should_request_be_blocked(&Request {
        url: Url::parse("https://www.evil.example/script.js").unwrap(),
        origin: Origin::Tuple("https".to_string(), url::Host::Domain("notriddle.com".to_owned()), 443),
        redirect_count: 0,
        destination: Destination::Script,
        initiator: Initiator::None,
        nonce: String::new(),
        integrity_metadata: String::new(),
        parser_metadata: ParserMetadata::None,
    });
    assert_eq!(check_result, CheckResult::Blocked);
}

Dependencies

~5.5–8MB
~140K SLoC