Craig Francis
banner
craigfrancis.bsky.social
Craig Francis
@craigfrancis.bsky.social
Security, Accessibility, Performance... trying to make the world better… live in Bristol, UK.
Glad to see “we won't be removing XML from the browser”… while it can be tricky to use `application/xhtml+xml`, and there are small rendering differences to plain HTML, it’s a really good dev mode, e.g. ensuring all attributes are quoted (could be a security issue), and all tags nested correctly.
November 12, 2025 at 10:44 PM
Looking good… and while I know Injection Vulnerabilities stay there, because they are still common, I’m annoyed our industry keeps saying “just learn how to do it right, and never make a mistake” (I think the only fix is to require the use of “developer defined strings”).
November 7, 2025 at 10:51 PM
Just have a mid-life crisis like most people (the less dignified the better)… I hit my 40th like a brick wall, while I’m still mostly programming, I’ve also moved into childcare (it’s fun, but maybe a motorbike would have been more sensible).
November 5, 2025 at 7:37 AM
I know it’s been a long process, but I *really* hope this works, thank you for input on this, and, well everyone who has contributed :-D
November 3, 2025 at 10:36 PM
If you prefer to go by examples, I’ve got one at:
eiv.dev/trusted-types/
October 16, 2025 at 7:38 AM
Looks like StackOverflow has eaten my comment… just to note:

7. Apply variables to safe attributes only

9. Avoid problematic functions

Trusted Types is helpful here, it’s enabled via CSP, the browser will then block all of these unsafe features by default (with a bypass for the special cases).
October 16, 2025 at 7:37 AM
Oh dear, but on the plus side, Python has the LiteralString type, added in 3.11 (via PEP 675).

So all Python frameworks can completely prevent SQL Injection, by simply ensuring the SQL is a LiteralString (i.e. a developer defined string, while using Parameterised Queries for user values).
September 24, 2025 at 6:42 PM
Content-Security-Policy (with Trusted Types)… I have a website with 1 page with 1 XSS vulnerability (only available on the test server); when it’s pen-test time, I wait to see if the testers find the vulnerability (50%) and then see if they could do anything with it (nothing yet).
September 19, 2025 at 8:35 PM
Sorry I’m being lazy, I was involved with the testing of the Google Chrome implementation (I made the first production website to use Trusted Types), so while I’m not pretending to know everything, I don’t think I’m the intended audience, just a big fan, and glad you’re teaching this stuff :-)
September 18, 2025 at 9:01 PM
I’m being lazy, but I assume you’ve covered…

Content-Security-Policy: […]; require-trusted-types-for 'script'; trusted-types 'none';

I *really* like Trusted-Types, but I don’t think many developers know about it.

I want to dangerous APIs (like innerHTML) to be replaced be safe-by-default APIs.
September 18, 2025 at 7:57 PM
Can I add, I don’t think developers should ever escape values (we get it wrong too often), instead use libraries which always do it correctly (e.g. Context Aware HTML templating engines); also SQL must be a “developer defined string” (the programming language must enforce parameterised queries).
September 15, 2025 at 5:29 AM
I had a baby next to me once, their first flight, parent had tried to be prepared, but during take off, the baby looked directly at me, with that “wtf” look in its eyes, I smiled and looked happy/excited, and I could actually see the thought click in to place (got 1 happy baby, and a quiet flight).
September 13, 2025 at 7:33 AM
Or, while AI can help, and provide fairly acceptable responses, it’s possible we are being tricked into thinking AI is more capable than it actually is (by companies trying to sell it), so the massive amounts of investment might not pay off (see also the dot com bubble, and burst).
September 10, 2025 at 6:43 AM
What I was getting at - I hope for a future where the easy to do is the secure option, with programmers having to really go out of their way to do something dangerous.
August 9, 2025 at 2:17 PM
Why is the last one the easiest to type, read, and dare I say it understand?

(not actually understand, if you did then you wouldn’t do this, but anyway).
August 8, 2025 at 10:53 PM
This is one of my baby plants :-)
June 12, 2025 at 11:24 AM
With identifiers in SQL, this should either be a developer defined string in the SQL (e.g. have an allow-list array, where the key is an alias or numeric offset, the values are the SQL)… or, your database abstraction should have a way to parameterise, e.g. $aliases in:
github.com/craigfrancis...
php-is-literal-rfc/examples/sql-basic.php at 9e9223a4b98987166938f53b4c4bd37ed7cd50e9 · craigfrancis/php-is-literal-rfc
Proposal for the `is_literal()` function. Contribute to craigfrancis/php-is-literal-rfc development by creating an account on GitHub.
github.com
February 8, 2025 at 11:35 AM
Yep, I’ve got some examples in PHP:
github.com/craigfrancis...

If memory serves, you’re using Go atm; so this is how I would start, with a package that’s for the database abstraction (maybe taking an SQL string, or individual parameters for an ORM):
github.com/craigfrancis...
February 8, 2025 at 10:53 AM
I would add that developers still make mistakes with prepared statements (especially when the SQL string is built via complex conditions/concatenation/etc, or junior developers make edits), so you must also validate the SQL strings are developer defined:
eiv.dev
February 7, 2025 at 9:26 PM
Agree completely, it’s why I see all automated pen test results as the first draft… they are just the start of an investigation, where results could be discounted immediately, or be part of a discussion with the developer. Also, no found “issues” does not mean the system is 100% secure.
January 20, 2025 at 5:25 PM
I believe it’s to cover a user following a link to the API (maybe from an email, or malicious link), if the API can return HTML content, it would be like a normal web page for the browser; so pen test tools like to see a ‘none’ CSP.
January 20, 2025 at 1:43 AM
It’s how they got it to work, while they take a HTML string, a different package could take a CLI string in the same way.

So the functions first argument can be “convert ? -resize ? ?”, and because it’s unexported, that must be provided during compile time.
January 9, 2025 at 12:39 PM