Hacker Newsnew | past | comments | ask | show | jobs | submit | jeremyevans's commentslogin

"freezer" was my originally desired name for this gem, but it was already taken.


It's cool to see this posted here. Refrigerator has been around for a number of years, but it doesn't get much press. It was originally developed as part of my work getting production Ruby web applications to run in chroot environments, where you cannot load libraries after chrooting (for more details, see https://code.jeremyevans.net/presentations/rubyhack2018/inde...). This allows you to emulate that type of chroot restriction without superuser access. It also allows you to detect monkey patches of core classes in libraries.

Note that it doesn't prevent or discourage monkey-patching, it just requires that you apply your monkey-patches before freezing the core classes. The idea here is similar to OpenBSD's pledge, where startup and runtime are considered different phases of an application's lifecycle. After startup, you limit what the runtime can do. With refrigerator, you freeze the core classes at the end of startup. So monkey patches are allowed during startup, but not at runtime.


There is a Ruby form library named Forme that works this way for Roda and Sequel (https://forme.jeremyevans.net/files/README_rdoc.html#label-R...). As you expect, this makes handling normal HTML form submissions much easier.


just want to say Roda and Sequel deserve a better marketing, you need a dhh, as they are great!


That's the most recent audited report. Auditing the state's entire financial report takes a long time. The report for year ended June 2020 should be published later this month (scheduled for December 22), according to the California State Auditor: https://www.auditor.ca.gov/bsa/aip


OK, I'll buy that. But why is the first link hidden behind a login? https://suppliers.fiscal.ca.gov/


That I cannot answer (not sure where that link comes from, maybe nonameiguess can tell you). Looks like suppliers.fiscal.ca.gov is a externet location for vendors that do business the state, not a public website.


If you're using X, the fluxbox window manager supports tabbed windows: http://fluxbox.org/


> I'd just like to point out that a lot of RDBMSs support storing date and time alongside timezone information directly without using two separate fields. SQL Server has datetimeoffset, PostgreSQL has timestamp with time zone, and Oracle has timestamp with time zone.

PostgreSQL's "timestamp with time zone" doesn't store timezone, it converts the time to UTC and stores that, and on retrieval converts the value to the connection's time zone.


Part of the problem is the ANSI SQL standard specifies that 'TIMESTAMP' does not have any offset/timezone applied. The postgres docs pretty much admit this is a bad idea and recommend all timestamps be stored as 'TIMESTAMPTZ' (aka TIMESTAMP WITH TIME ZONE).

It's problematic when moving data between systems with different Locale settings. Because ANSI timestamps are stored as 'local' time, timestamps will shift if you read from a DB in New York and write to one in San Francisco. Both will interpret an ANSI SQL timestamp as being in their locale unless told otherwise.


Yeah, that's true. That's closer to Oracle's TIMESTAMP WITH LOCAL TIME ZONE data type. In PostgreSQL you have to use the AT TIME ZONE to override the output time zone, so the client has to know which time zone they want. And I'm sure there are weird corner cases where information is lost.


That sounds dumb (if column type is called like that text in the quotes)


Might sound "dumb" or confusing (which it is), but makes a lot of sense. I've written a post explaining the difference between "timestamp with/without time zone": http://phili.pe/posts/timestamps-and-time-zones-in-postgresq...


Why? If you're doing things correctly, you don't need to specify data types particularly often in SQL. You specify it once when the table is created and that's it. All you care about on the programming interface is that your application knows what data type of your language to use with each data column. What's wrong with a verbose and descriptive name for a data type?


I don't think they're saying that having verbose name is dumb, I think it's that a type called "timestamp with time zone" doesn't actually store a time zone.


Yeah, that's what I initially thought, too, but some of the other responses have made me question that.


SQL data types have some verbose names, like "NATIONAL CHARACTER VARYING (20)". PG adds a "TIMESTAMPTZ" as alias for "TIMESTAMP WITH TIME ZONE" (which I'm not sure whether is a sql ansi standard type or just convention).


It is, and it is.


In case you are wondering how it handles password encryption and storage, it appears to use a custom password hash based on SHA256 and scrypt: https://github.com/18F/identity-idp/blob/980c2aa26397f530673...

Passwords appear to be stored in the users table in the "encrypted_password" column, and it does not appear that any database-based security is used. This is one RCE/SQLI vulnerability away from exposing the password hashes for all users. To be fair, that's probably true of most sites that store password hashes, but I would have expected better from 18F.


Can you elaborate on what you were hoping for?


Restricting access to the password hashes using database security so that a vulnerability in the web application cannot expose password hashes unless a separate vulnerability in the database was also exploited. In PostgreSQL (and other SQL databases), this generally involves having multiple database users with separate permissions, making it so that the database user the web application uses doesn't not have SELECT permissions for the password hash column.

If you want an example for a Ruby authentication library that does this, there is Rodauth: https://github.com/jeremyevans/rodauth


Or maybe they have stronger access controls within their production environment and we don't see that specific configuration in the code?


That could be the case, but if you are going to open source the application, what would be the point of trying to hide it?

Considering that password hashes are stored in the users table, it seems unlikely. While you can use PostgreSQL to implement per-column permissions, it's a fairly large pain, and you have to make sure every query you are using that selects from the table does not select that column. Rails/ActiveRecord by default selects all columns in the model's table, and it's a fair amount of work to work around that.


what is database-based security?


It's an old craft that died somewhere around the dotcom hype in 2000.

It works with SQL, using language elements like VIEW, PROCEDURE, ROLE and GRANT

SQL Databases can still do it, but people who know how to use it are all retired or work in management now. :-)

Also: no web framework knows how to deal with it.


Based upon the various negative findings by the GSA IG's office I don't expect much from 18F. If you can't be bothered to comply with required government IT security requirements why should I trust you to comply with the ones you have made up for yourself.


That isn't a problem in Sequel, as you can pass a complex expression to #or, in which case it works as you would expect it to:

    Post.where(id: 1).or(Sequel.&({:id=>2}, {:name=>'Foo'}))
    # SELECT * FROM posts WHERE ((id = 1) OR ((id = 2) AND (name = 'Foo')))


Yay, Jeremy Evans spreading some Sequel knowledge ^_^

Big fan of Sequel; it's super sleek. As a side-note to Jeremy's comment, while (i guess) he used Sequel.& to demonstrate that OR and AND conditions can be combined freely, there are more succinct ways of expressing that particular query:

  # Using the a "virtual row" block:
  Post.where(id: 1).or{(id =~ 2) & (name =~ 'Foo')}

  # Or, if you don't fancy that kind of block magic, simply passing a Hash, 
  # the same way as with .where
  Post.where(id: 1).or(id: 2, name: 'Foo')


That doesn't appear to work:

    Post.where(id: 1).or Post.joins(:author).where(author: { name: 'John' })
    ArgumentError: Relation passed to #or must be structurally compatible. Incompatible values: [:joins, :references]
It appears that only the filter clauses are allowed to be different (similar errors if :select, :order, :group, :limit are different), in which case it's no more powerful than Sequel, just more of a pain to use. You can easily implement ActiveRecord's behavior in Sequel if you want to combine filter clauses for arbitrary datasets:

    ds = Post.where(id: 2)
    Post.where(id: 1).or(ds.opts[:where])
It's also interesting what happens if you mix where and having clauses (I'm not saying it doesn't make sense, but it may bite someone):

    Post.where(id: 1).or(Post.having(id: 2)).to_sql
    # SELECT "posts".* FROM "posts"


"s-q-l". It is ambiguous if pronounced "sequel". :)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: