-
-
Notifications
You must be signed in to change notification settings - Fork 151
[vectors/color] Content Security Policy use of eval / Function #497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @dennemark — wow, I wasn't aware that this has such an impact, and it seems switching to actual source code generation seems to be the only safe solution to this problem, But:
Will have to research this more, please bear with me... 🤔 🙏 |
I see.. that can be pretty annoying. CSP was a rabbit hole for me too the last few days. Changing our backend and the prior backend just did not use it. I am not even sure, if this will be the only situation where i will face unsafe-eval, since we also have some wasm modules. Concerning that wasm also is unsafe, I feel I mainly have to make sure that we use trustworthy third-party modules. Other than that inline scripts are only allowed via nonces, so that gives safety, I assume. |
- this new code generator consumes existing vector fns and re-emits them as source files - initial proof-of-concept only, WIP
@dennemark I just imported a new proof-of-concept code generator which consumes existing vector fns and re-emits them as source files into a new directory. I think this will work, in principle, for the vectors package, but as mentioned earlier, the resulting package size will be MUCH bigger, but there're also some positive aspects, e.g:
Here's some example output for just the import type { MultiVecOpVV } from "./api.js";
import { vop } from "./vop.js";
import { add2 } from "./add2.js";
import { add3 } from "./add3.js";
import { add4 } from "./add4.js";
/**
* Multi-method. Componentwise nD vector addition. Auto-delegates to optimized
* versions where possible.
*
* @param o - output vector
* @param a - input vector
* @param b - input vector
*/
export const add: MultiVecOpVV = vop(1);
add.default((o,a,b) => {
!o && (o=a);for(let i=a.length;--i>=0;) {o[i]=a[i]+b[i];}return o;
});
add.add(2, add2);
add.add(3, add3);
add.add(4, add4); import type { VecOpVV } from "./api.js";
/**
* Componentwise 2D vector addition.
*
* @param o - output vector
* @param a - input vector
* @param b - input vector
*/
export const add2: VecOpVV = (o,a,b) => {
!o && (o=a);o[0]=a[0]+b[0];o[1]=a[1]+b[1];return o;
}; import type { VecOpVV } from "./api.js";
/**
* Componentwise 3D vector addition.
*
* @param o - output vector
* @param a - input vector
* @param b - input vector
*/
export const add3: VecOpVV = (o,a,b) => {
!o && (o=a);o[0]=a[0]+b[0];o[1]=a[1]+b[1];o[2]=a[2]+b[2];return o;
}; import type { VecOpVV } from "./api.js";
/**
* Componentwise 4D vector addition.
*
* @param o - output vector
* @param a - input vector
* @param b - input vector
*/
export const add4: VecOpVV = (o,a,b) => {
!o && (o=a);o[0]=a[0]+b[0];o[1]=a[1]+b[1];o[2]=a[2]+b[2];o[3]=a[3]+b[3];return o;
}; I will continue with this over the coming weeks, but it's a major undertaking and I still haven't looked deeper into the impact of the color & pixel packages... |
Super nice!
Wondering how the package size impact will be. I guess having two different imports is not a good solution right? So one could choose i.e. @thi.ng/vectors/opt as import and would get the better bundle size. |
@dennemark made a lot of progress on the codegen/converter, now already more than 1/3 updated. I think the larger bundle size only has an impact when using full pkg imports without a bundler involved, but otherwise I'm actually getting smaller file sizes for some of the examples I've already tested... Btw. I don't think having two versions of the vectors pkg is feasible, neither from a usage nor maintenance point of view... The pkg is used as dependency for many others, and these packages will need to make a decision — too much complexity, easier to just have one... |
Nice sounds good! Does it make a huge difference for importing vector or colors pkg? Since it is quite convenient to import them via But sounds like a good approach then! |
@dennemark If you're using a bundler, then package-level imports like import * as vec from "https://esm.run/@thi.ng/vectors"; ...but for this kind of usage, such package-level imports are a bad form for any larger package, and the generally best practice there is to always handpick the imports you actually care about, e.g. import { distSq2 } from "https://esm.run/@thi.ng/vectors/distsq"; One thing I'll look into (at a later stage) is to maybe split up the vectors package into 2D, 3D, 4D and nD versions, but for that we will first need this codegen business fully completed... |
- update FnSpec - add boolean & strided vector ops
Thanks for the clarification! Concerning the vectors packages split up... will it have some advantages to split it up? Since it currently also works well no? |
- add various random ops - add most strided ops - update doc string handling/interpolation - add support for dimensional variations in doc links - collect total file sizes
@dennemark I'm only looking into splitting up as an option due to the (quite!) larger package size (currently, 280KB of source code — also caused by a lot more and largely duplicated doc strings present). I really want to keep the package usable for non-bundling workflows (btw. just out of interest: are you using any bundlers yourself?). There're quite a few possibilities for splitting, but my current thinking is:
I could also imagine both the thi.ng/vec-nd and thi.ng/vectors packages to be kept as one, but having the plain, non-polymorphic nD functions separate would be beneficial... The The main benefit of this structure would be smaller packages (with less dependencies) when only using the 2D/3D/4D/nD features individually. E.g. thi.ng/geom would only require the vec2/3 packages. thi.ng/color would just need the vec4 package etc. Again, this is all needing some experimentation & testing, but I'm now mostly done with the codegen and will concentrate on this next... |
Ah wow, i am so used to bundlers now, that I did not expect you paying so much attention on non-bundling workflow. I use vite and just strip away all comments or docs. I remember in 2017 or so I did not program for the web for years and started importing via script tags and was happy that it worked. Our main app where we use thi.ng is a SPA with a login, so bundle size does not matter too much. Even though it could improve loading times here and there.. I like the approach of combinig the sub vec packages in thi.ng/vectors so it would not be really a breaking change. But also it could clarify usage a bit more clearly. So when is vec2 or vec3 used. Good idea. Close this issue when you feel comfortable about it! |
BREAKING CHANGE: Due to major refactoring & restructuring related to #497, some direct imports & function names have changed - replace former codegen approach with higher-order functions - split up various operations into more granular source files - add doc strings for almost all functions (🎉 — lack of was a former major criticism of this pkg) - update/remove deps
BREAKING CHANGE: Refactoring & restructuring related to #497 - replace former codegen approach with higher-order functions - add new`defMath()` & `defMathN()` impls
* feature/vec-splitup: (24 commits) test(color): update `random` test consts fix(matrices): minor update `identity()` refactor(shader-ast-js): internal updates (imports & renames) refactor(imgui): minor internal updates (imports) refactor(color): minor internal updates (imports) refactor(tsne): minor internal updates refactor(matrices): update to remove dynamic codegen (#497) feat(vectors): replace 99% of vector ops with new versions build: update yarn lock feat(vectors2): copy tests from old pkg feat(vectors2): add random ops for strided vectors feat(vectors2): add randNormS() fix(vectors2): fix normalizeS2/3/4() fix(vectors2): fix fit3/4 feat(vectors2): add/update various ops chore: remove obsolete/experimental vector pkgs feat(vectors2): import as new pkg (temporary only, will replace vectors pkg) feat(vec3): add/update/replace/rename various ops refactor(vec2): add/update/merge various ops/files feat(vec2): add/update ops ...
Hi @dennemark — just a quick update to say that I've already replaced the vectors package on the In terms of file size impact: The FULL minified pkg bundle is now 56.4KB vs previously 48.5KB, however the code density has improved and the brotli-compressed pkg size is only 1KB larger, which I found absolutely incredible! 🎉 Also — more importantly — many of the examples in the repo are showing between 5-25% smaller result bundle sizes, some also have become slightly larger, but so far I found the most by only ~2%... Related to this change: I've also updated the color & matrices packages to be free from dynamic code generation now! The only packages still using
I will do more testing over the coming days, then release new version(s) asap... |
Wow that is amazing! Nice bundle size still is small or even smaller than before! |
Hi @postspectacular ,
not sure how you think about this issue, since it goes bit deeper into your vector and color functions:
I am using
@thi.ng/color
in frontend and it importsclamp
and later on acompileHOF
function that callsnew Function
. Now if I want to set Content Security Policy on my backend, my browser complains that I am using 'eval/Function'. To avoid this I have to state on 'script-src': 'unsafe-eval'. While this is ok for thi.ng library, it however opens up possibilities for other attack vectors.So I was wondering, if it would be possible to actually compile these functions for the shipped code, since then the
compileHOF
would not be necessary anymore.I think it is also a problem of thi.ng/vectors, since compileHOF is within this package.
Let me know what you think.
The text was updated successfully, but these errors were encountered: