sergiobenitez / cookie-rs Goto Github PK
View Code? Open in Web Editor NEWHTTP cookie parsing and cookie jar management for Rust.
Home Page: https://docs.rs/cookie
License: Apache License 2.0
HTTP cookie parsing and cookie jar management for Rust.
Home Page: https://docs.rs/cookie
License: Apache License 2.0
The SignedJar doesn't have iteration methods. How to iterate over cookies in this case?
See rwf2/Rocket#1151.
Percent signs in names and values should be encoded if they are going to be decoded later.
Why the lifetime of parameters to create a new cookie Cookie::build(name, value)
is static
?
I hit a problem with cookie-rs as used by Servo.
A full and unnecessary long explanation is online.
It comes down to this: cookie-rs percent-decodes key and value when parsing and stores them as Strings.
Servo uses these without modification to send back as a HTTP header.
This breaks if the cookie is not to be interpreted as a percent-encoded value (e.g. having newlines %0A
or things that make it invalid UTF-8: %EE
).
The actual decoding dates back to last year.
It's undocumented and suprising IMO.
Any insights on why it was done this way?
P.S.: Also on Display
only the value gets re-encoded, the key is used as-is, which is even more surprising.
This might be a stupid question, but does the time
crate offer anything in addition to std::time
? Replacing it would be a breaking change, but is there more to it?
Let's say I only use Cookie
temporarily to parse a cookie string I received in an HTTP header. In that case, I have the underlying string already allocated, and call parse
on that to get a Cookie<'c>
that has the lifetime 'c
that is at maximum as long as the lifetime of the allocated string.
However, I'm only interested about the value of the cookie, not anything else, so I want to call .value()
, get a &str
to the value and discard the cookie struct as a temporary.
Currently this crate doesn't seem to support an usage like that. The problem is that .value()
returns a &str
that has the same lifetime than &self
that was passed to the .value()
method. If the returned &str
had the same lifetime than the underlying allocated string, I could discard the cookie struct, but now I can't.
Is it possible to change that .value()
returns &'c str
? instead of &str
?
Some frameworks puts control characters into cookies. In my case, Revel puts NUL in cookies percent encoded.
The current API doesn't allow straight handling of this (I need to go through percent_encoding
directly).
What is the current MSRV for Cookie, and the threshold for upping it? As the revamped time crate is nearing release, it looks doable to update the dependency here. However, the MSRV for that is 1.40.
Both of these would changes would necessarily bump the MSRV (and necessitate a 0.13 release), though #[non_exhaustive]
would be useful elsewhere as well.
Basically, I'd like to make changes similar to those I made for Rocket (which were well-received!). I'm just curious if bumping the MSRV is allowed, and by how much.
0.6 is out and this is still pinned to the 0.5 range, causing a build failure for hyper.
Thanks for the library! As the title mentions I am having problems compiling openssl with rust. rust-crypto crate has HMAC implementation so is this possible?
The usual :)
Since ring 0.13.
will be yanked soon, we need a new version of cookie
asap so that we would have version with bumped cookie
dep
CC owners @SergioBenitez @alexcrichton
The current cookie.fmt()
function outputs a cookie useful for the Set-Cookie
header, but not the Cookie
header. I've settled to just doing write!(f, "{}={}", cookie.name, cookie.value)
in hyper, but perhaps that should live in this repo?
Can/should the CookieJar
type (unsafely) implement Send
? Or perhaps one of its component types. It's rather prohibitive right now that it doesn't.
So that hyper can get on crates.io
cookie-rs currently uses AES-256-CBC and then HMAC-SHA1 in encrypt-then-MAC. This is secure, since AES-256-CBC and HMAC-SHA1 are both individually secure and because they are used in encrypt-then-MAC.
However, neither AES-256-CBC nor HMAC-SHA1 is fast, even when AES is hardware accelerated (due to the serial nature of CBC mode). ChaCha20-Poly1305 is much faster.
Again, cookie-rs's current crypto is not insecure, just slow.
I was talking to @seanmonstar in #hyper earlier tonight, and he said that he wasn't sure if cookie::jar was named correctly:
I think the jar in cookie is not what we typically think of for a jar usually a jar is what the user agent has, but the cookie crate's version is more like what many would think of as a session
...
usually, a session is when a server receives a request, looks in its cookie headers for some state, and then the server possibly updates that session, which results in probably new Set-Cookie headers being sent
its only for a single user, and their interaction with that specific server
whereas a jar, in user agents, holds all the cookies the browser has seen for that user, for any website
If it's the case that "jar" is mainly used for user agents, but the current module is designed for servers, should we consider renaming this module to something else?
Maybe add Cookie::parse_bytes
to avoid breaking changes.
It would allow actix-web to detect some cases when the key for private cookies is leaked (actix/actix-web#734)
Edit: after all it seems impossible to add this feature without breaking changes...
failures:
---- src/jar.rs - jar::CookieJar::iter (line 320) stdout ----
thread 'src/jar.rs - jar::CookieJar::iter (line 320)' panicked at 'test executable failed:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `4`,
right: `3`', src/jar.rs:19:1
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
', src/librustdoc/test.rs:372:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
failures:
src/jar.rs - jar::CookieJar::iter (line 320)
// parse.rs:160
let domain = match v.starts_with('.') {
true => &v[1..],
false => v,
};
What is the purpose of this? I believe that the leading full stop is not meaningless as cookies for .example.com
are visible to sub.example.com
whereas the ones for example.com
are not.
From http://tools.ietf.org/html/rfc6265#section-5.2 the secure attribute may have a value (which must be ignored).
This means that a cookie like foo=bar ;HttpOnly; Secure=aaaa
should set the secure flag of cookie to true, which is not the case right now.
I catched this bug by running the cookie test suite from https://github.com/abarth/http-state (see tests test_attribute000[4578]) which is focused on the secure flag. But the same goes for other attributes like httponly.
I will propose a fix soon.
Currently, cookie-rs's Cargo.toml specifies using Rust-OpenSSL version 0.7.0
. At the time of this writing, the latest release is version 0.8.2
, which includes a number of bug fixes that, in some applications has resolved some functional failings.
I'd like to ask for cookie-rs to adopt these changes and upgrade to the latest version.
Hello @alexcrichton, what do you think about implementing an encrypted cookies support? It is quite useful for some cases, e.g. storing user sessions on the client side.
Will it be hard to implement? Probably I can do it myself if you will agreed to add such functionality.
I realize its an optional feature, but even libraries that don't care care about signing cookies are still disrupted when breaking changes of ring are released (for example, seanmonstar/reqwest#517). If they were separate crates, the core Cookie
API could be more stable, and then only cookie-secure
(naming is hard) would ever need to update for new ring versions.
So depending on rust-url and cookie-rs at the same time causes conflicts, unless I force the version back down to 0.1.0. Is it necessary to include the version here when depending on the git version?
Hello! What do you think about adding some indirection over the ring APIs used in this crate and optionally allowing users to choose openssl/boring/mundane/etc for their crypto implementation? It would obviously have (potentially severe?) security and ergonomics tradeoffs to consider, but having a more stable option would be very nice given the recent mass-yanking of ring versions.
Is there any good reason CookieJar doesn't derive/implement the Debug trait?
How to clone a Cookie
to a specific lifetime? For example,
struct NaiveCookieJar<'a> {
data: HashMap<(String, String), Cookie<'a>>,
}
impl<'a> NaiveCookieJar<'a> {
fn add(&mut self, domain: &str, name: &str, cookie: &Cookie) -> bool {
/* this works for static 'a
self.data
.insert((String::from(domain), String::from(name)),
cookie.clone().into_owned())
.is_some()
*/
self.data.insert((String::from(domain), String::from(name)), cookie.clone()).is_some()
}
}
This code resulted in error: E0495: cannot infer an appropriate lifetime for lifetime parameter 'c
due to conflicting requirements
It seems that cookie.clone()
is not working because Cookie
holds a Cow<'a, str>
. Then what is the proper way to do this?
Not doing so blocks three of my projects from using the latest version of ring
.
heartsucker/rust-secure-session#6
heartsucker/iron-csrf#13
heartsucker/rust-csrf#9
This is a follow-on from taskcluster/rust-hawk#14, where @eoger mentions that old versions of ring are regularly yanked. In particular, this is preventing me from using the latest rust-hawk with rocket:
error: failed to select a version for `ring`.
... required by package `hawk v1.0.5`
... which is depended on by `rocket-play v0.1.0 (/home/dustin/tmp/rocket-play)`
versions that meet the requirements `^0.14.5` are: 0.14.6, 0.14.5
the package `ring` links to the native library `ring-asm`, but it conflicts with a previous package which links to `ring-asm` as well:
package `ring v0.13.5`
... which is depended on by `cookie v0.11.0`
... which is depended on by `rocket_http v0.4.0`
... which is depended on by `rocket v0.4.0`
... which is depended on by `rocket-play v0.1.0 (/home/dustin/tmp/rocket-play)`
I see that ring is already upgraded in master, but not released. Would you consider making a release?
Like many I read the Cross-Site Request Forgery is dead! blog post 2 days ago and I thought it would be nice to use. It's currently only supported by Chrome.
Since the Err case returns unit, it may as well be an Option?
The current default value for the path
field for Cookie
is Some("/")
. I'm using this crate from a user agent perspective, and per IETF RFC 6265 Section 5.1.4, a user agent should set the path based on the request-uri if it is not set via the Path attribute; e.g. should be "/foo/bar" for a cookie resulting from a request to "http://example.com/foo/bar/" if no Path attribute is included. With the current behavior, it is impossible for client code to distinguish if the parsed cookie contained no Path attribute, or "; Path=/", and as such cannot know when to set it from the request-uri.
Can I open a discussion on potentially splitting this into two separate crates, one for cookie jars + signing, and one for general purpose cookie parsing?
At it is right now this crate does two quite different things:
Even if un-used, the second feature existing comes with a price - Hyper no longer imports this crate due to the optional dependency on openssl. Upshot: it's now no longer possible to parse cookies out of the box in Iron.
If the features were split into two different crates then crates like Hyper (and anyone else only wanting to parse cookies, not sign them) could continue using the nice API here for that, and people who still want both would be unaffected (there's no reason the public API of this crate would need to change at all).
I'd love to add Jar support into hyper. At the moment, to support the delta function, I get back a vector or strings that I need to slice the header label off, and then write to a stream.
Or update them super frequently, which is probably a huge pain.
Right now the explicit dependency on an old version is causing build failures of this package and subsequently hyper.
I'd like signatures on cookies to include expiration date and path as well. The signature could still be inside the cookie value.
I would love to prepare a PR for this, but I'm unsure how to design this in a backwards compat way (or if that is even necessary).
Basically what the title says. For example the docs imply that httponly
is a public struct field.
When a cookie is removed from the Jar, it only records the cookie's name. So when the Set-Cookie header is generated to clear the cookie, the header does not have the Path or Domain parameters, even if the original cookie had them. This is a problem because the new Set-Cookie header only overwrites the previous cookie if the Path and Domain parameters match.
https://github.com/alexcrichton/cookie-rs/blob/master/src%2Fjar.rs#L297
Right now this uses a variable time comparison, potentially leaking data to an attacker, see http://codahale.com/a-lesson-in-timing-attacks/
Z85 is like Base64, but instead of encoding 3 bytes in 4 ASCII characters, it encodes 4 bytes in 5 ASCII characters. The constraints placed on the design of Z85 also happen to make every Z85 encoding character a valid cookie value character. (Valid values in a cookie value are documented as cookie-octet
in RFC 6265 Section 4.1.1.
In the case of HMAC-SHA256-signed , this would reduce 12 bytes of base64-encoding overhead to 8 bytes of Z85 encoding overhead, which isn't really significant. For encrypted-and-signed cookies the savings could be more significant.
This would remove the rustc-serialize dependency, which also seems desirable. (This could also be done by switching to the base64 crate or an alternative.)
It appears it's possible to set the path but is it possible to unset it once it's set? Passing ""
doesn't help..
Current signed method requires &mut self
even if you need only reading the value. And I guess PrivateJar has the same problem.
Are there any chance to support read only SignedJar that can be obtained from non-mutable self
and serves only get
method?
Thanks for the great framework.
I am trying to use merkle tree from spinresearch but i am getting a dependency error.
error: failed to select a version for ring
.
... required by package merkle v1.11.0
... which is depended on by filtering-service v0.1.0 (/Users/alakazam/Documents/projects/RUST/filtering-service)
versions that meet the requirements ^0.16.1
are: 0.16.9, 0.16.7, 0.16.6, 0.16.5, 0.16.4, 0.16.3, 0.16.2, 0.16.1
the package ring
links to the native library ring-asm
, but it conflicts with a previous package which links to ring-asm
as well:
package ring v0.13.5
... which is depended on by cookie v0.11.0
... which is depended on by rocket_http v0.4.2
... which is depended on by rocket v0.4.2
... which is depended on by filtering-service v0.1.0 (/Users/alakazam/Documents/projects/RUST/filtering-service)
failed to select a version for ring
which could resolve this conflict.
I tried using replace also but didnt work for me. Please can we do something @SergioBenitez @jebrosen
I want use rustls with cookie, but it depends on ring 0.13.0-alpha
use std::sync::{Arc, Mutex};
use std::thread;
extern crate cookie;
use cookie::{Cookie, CookieJar};
fn main() {
let m = Arc::new(Mutex::new(CookieJar::new(b"f8f9eaf1ecdedff5e5b749c58115441e")));
thread::spawn(move || {
m
});
}
This fails to compile with the following error message:
src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<std::collections::hash::map::HashMap<collections::string::String, cookie::Cookie>>` [E0277]
src/main.rs:10 thread::spawn(move || {
^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<std::collections::hash::map::HashMap<collections::string::String, cookie::Cookie>>` cannot be shared between threads safely
src/main.rs:10 thread::spawn(move || {
^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<std::collections::hash::set::HashSet<collections::string::String>>` [E0277]
src/main.rs:10 thread::spawn(move || {
^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<std::collections::hash::set::HashSet<collections::string::String>>` cannot be shared between threads safely
src/main.rs:10 thread::spawn(move || {
^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<usize>` [E0277]
src/main.rs:10 thread::spawn(move || {
^~~~~~~~~~~~~
src/main.rs:10:5: 10:18 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:10:5: 10:18 note: `core::cell::UnsafeCell<usize>` cannot be shared between threads safely
src/main.rs:10 thread::spawn(move || {
I've been looking for a consumer-side solution for over an hour now, but couldn't find one. Is the problem with CookieJar
itself?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.