- https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/#document-ready
- ~/Downloads/moving-from-jquery-to-vanilla-js.md
- https://gist.github.com/thegitfather/9c9f1a927cd57df14a59c268f118ce86#add-elements-to-the-dom-cont
- ~/Downloads/vanilla-js-cheatsheet.md
- Vanilla-todo: A case study on viable techniques for vanilla web development | Hacker News
node inspect app.js
# Input:
# repldebugger;
let user = null;
console.log({user});
console.log(arguments[0]);
console.table(["apples", "oranges", "bananas"]);
console.trace();
console.log(new Error().stack);
// Convert argument to string to avoid delayed evaluation in browser's dev tools including updates after log statement
let l = [];
l.push("1")
console.log(""+l); // Outputs: 1
l.push("2");
eval('console.log((function() { return !this; })());')
eval('"use strict"; console.log((function() { return !this; })());')
Object.defineProperty(navigator, 'webdriver', {
get: () => {debugger; return false},
});https://developer.mozilla.org/en-US/docs/Web/API/Console/count
env \
DEBUG='*' \
NODE_DEBUG='*' \
node -e 'console.log(2+2)'
# syntax check
node --check ./index.js
node --stack-trace-limit=100 ./index.js
node --cpu-prof --heap-prof -e "require('request')"
# On browser: F12 > Memory > Load profile...
# On browser: F12 > Performance > Load profile...
# -- https://electronjs.org/docs/tutorial/performance
NODE_OPTIONS="--perf-basic-prof --perf-prof-unwinding-info" npm run
artillery quick -r 200 -d 0 http://localhost:3000
sudo perf record -F 99 -g -p $NODEJS_APP_PID -- sleep 60
sudo perf script -f --header > stacks.test.$(date --iso-8601)
# -- https://medium.com/yld-blog/cpu-and-i-o-performance-diagnostics-in-node-js-c85ea71738eb
# --trace-sync-io
# Print a stack trace whenever synchronous I/O is detected after the first turn of the event loop.
# --zero-fill-buffers
# Automatically zero-fills all newly allocated Buffer and SlowBuffer instances.handler = {
apply: function(target, thisArg, argumentsList) {
}
}
window.open = new Proxy(window.open, handler);
Element.prototype.appendChild = new Proxy(Element.prototype.appendChild, handler);# debug and run script
node --inspect app.js
# debug and break before running script
node --inspect-brk app.js
# => chrome://inspect/#devices > Open dedicated Devtools for Node
# -- https://marmelab.com/blog/2018/04/03/how-to-track-and-fix-memory-leak-with-nodejs.html
# ||
npm install -g ndb
ndb node app.js-
https://nodejs.org/en/docs/guides/debugging-getting-started/
-
conditional breakpoint on func call
- debug(postMessage, 'arguments[1] == "*"')
-
log dom events for object
- monitorEvents(window, 'message')
-
modify dom response from requests
- overrides > enable local overrides
-
network tab - file dependencies
- ctrl-click JS and DOC
- shift-select file - other are highlighted
-
memory tab > heap snapshot - strings in memory
- retainers > object
- :) strings already concatenated / evaled, could be missed when searching source code
-
Improve Your Hacking Skills Using Devtools | Bug Bounty Tips - YouTube
https://eternalsakura13.com/2018/08/02/v8_debug/
# Output: package.json
npm init
# Output: .eslintrc.js
npm install eslint --save-dev
./node_modules/.bin/eslint --init
# ||
npm install typescripthttps://eslint.org/docs/user-guide/configuring
Testing:
Parsers:
- GitHub - posthtml/posthtml: PostHTML is a tool to transform HTML/XML with JS plugins
- https://eslint.org/docs/developer-guide/working-with-rules
- https://eslint.org/docs/developer-guide/selectors
Case Studies:
- ./wasm.md#optimizing-temporary-variables
- https://nullpt.rs/tackling-javascript-client-side-security-pt-1/
- ~/code/snippets/js/decode_jscrambler.js
cd some-dep
# Output: symlink at global modules dir, target is local `some-dep` dir
npm link
cd my-app
# Output: symlink at `my-app` modules dir, target is global `some-dep` dir
npm link some-depcd my-app
npm uninstall --no-save some-dep && npm install
cd some-dep
npm uninstallOn launch.json:
"runtimeArgs": [
"--preserve-symlinks"
]https://medium.com/dailyjs/how-to-use-npm-link-7375b6219557
"env": {
"node": true,
"commonjs": true,
"browser": true,
"es6": true
}"globals": {
"process": true
}https://stackoverflow.com/questions/50894000/eslint-process-is-not-defined
- Remove / Nullify URL parameters
- Concurrent requests / sessions
- e.g. remove element in one window, view same element in another window
- Misalignments when updating dynamic content
curl \
--http1.1 \
--include \
--no-buffer \
--header "Connection: Upgrade" \
--header "Upgrade: websocket" \
--header "Host: example.com:80" \
--header "Origin: http://example.com:80" \
--header "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==" \
--header "Sec-WebSocket-Version: 13" \
http://example.com:80/- https://github.com/Matt-Esch/virtual-dom
- https://reactjs.org/docs/reconciliation.html
- https://programming.vip/docs/realization-and-analysis-of-virtual-dom-diff-algorithm.html
- React in 33 lines | Hacker News
-
~/code/src/web/todomvc/examples/vanilla-es6/
-
~/code/src/web/todomvc/examples/vanillajs
-
https://stackoverflow.com/questions/34700438/global-events-in-angular
- selenium webdriver
- pyppeteer
- ~/code/guides/ctf/TFNS---writeups/2020-04-12-ByteBanditsCTF/notes-app/sources/mynotes/visit_link.py
- https://htmlunit.sourceforge.io/
document.querySelectorAll('iframe').forEach( item =>
console.log(item.contentWindow.document.body.querySelectorAll('a'))
)
setTimeout(() => Array.prototype.filter.call(document.querySelectorAll('a'), e => {return /evening/.test(e.textContent);})[0].click(), 2000)/*
Conversion to Array turns holes into undefined elements:
> Array.from([,])
[ undefined ]
> [...[,]]
[ undefined ]
*/
0 in [...[,]]; // true
/*
`in` detects properties, Array elements are props and holes are missing props:
> Reflect.ownKeys(['a', 'b'])
[ '0', '1', 'length' ]
> Reflect.ownKeys([,])
[ 'length' ]
*/
0 in [,]; // falseFunction.prototype.toString
o=window; do Object.getOwnPropertyNames(o).forEach(name => {console.log(name, o[name]);}); while(o = Object.getPrototypeOf(o));
// Globals
Object.entries(window)node --print-opt-code- https://insert-script.blogspot.com/2019/07/errorpreparestacktrace-allows-to-catch.html
- https://portswigger.net/blog/json-hijacking-for-the-modern-web
npm ls
yarn why
npm shrinkwrap- https://docs.npmjs.com/files/package-locks
- https://yarnpkg.com/lang/en/docs/selective-version-resolutions/
vim package.json
rm package-lock.json
npm installnpx some-package
# ~=
npm install some-package
./node_modules/.bin/some-package- Hidden but readable immutable properties, all values are unique
Object.getOwnPropertySymbols()- https://medium.com/intrinsic/javascript-symbols-but-why-6b02768f4a5c
- https://developer.mozilla.org/en-US/docs/Glossary/Symbol
// https://github.com/petkaantonov/bluebird
Promise.longStackTraces();
// || manual
Promise.resolve()
.then(outer)
.then(inner)
.then(evenMoreInner())
.catch(function (err) {
console.log(err.message);
console.log(err.stack);
});async foo() {}
// ==
const foo = () => new Promise(resolve => resolve())
await Promise.all([..., ...])
// ==
return { foo: await x, bar: await y }- Javascript DeObfuscator
- de4js | JavaScript Deobfuscator and Unpacker
- JS NICE: Statistical renaming, Type inference and Deobfuscation
- bumperworksonline.js · GitHub
- Beating JavaScript obfuscators with Firebug
// Running:
// - VM or sandbox - e.g. https://repl.it
// - "Pause script execution" > drop script in console > hit enter
var _original_unescape = window.unescape;
window.unescape = function() {
var u = _original_unescape.apply(this, arguments); // this calls the _original_ function
console.log('unescape ', arguments, u);
return u;
}
var _original_fromCharCode = String.fromCharCode;
String.fromCharCode = function() {
var u = _original_fromCharCode.apply(this, arguments);
console.log('fromcharcode ', arguments, u);
return u;
}
var _original_eval = window.eval;
window.eval = function() {
var args = arguments;
console.log('eval ', arguments, u);
var u = _original_eval.apply(this, arguments);
debugger;
return u;
}- ~/code/snippets/js/anti-anti-debugger.js
- Log firefox's
EvalKernel()- https://searchfox.org/mozilla-central/source/js/src/builtin/Eval.cpp#224
- https://nullpt.rs/tackling-javascript-client-side-security-pt-2/
#include "mozilla/Logging.h" // ... static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, AbstractFramePtr caller, HandleObject env, jsbytecode* pc, MutableHandleValue vp) { // ... using mozilla::LogLevel; static mozilla::LazyLogModule sLogger("example_logger"); MOZ_LOG(sLogger, LogLevel::Info, ("Eval: %s", JS_EncodeStringToASCII(cx, v.toString()).get())); // ... }
- Given integrity checks and debugger calls evaluated in a separate context, then replace firefox's debugger keyword
- usage
<script> window.oldSlice = Array.prototype.slice; Array.prototype.slice = function() { overriden_debugger; window.oldSlice(arguments); } </script> <script src="./foo.js"></script>
- e.g. JScrambler
- https://nullpt.rs/evading-anti-debugging-techniques/
--- a/js/src/frontend/ReservedWords.h +++ b/js/src/frontend/ReservedWords.h @@ -20,7 +20,7 @@ MACRO(catch, catch_, TokenKind::Catch) \ MACRO(const, const_, TokenKind::Const) \ MACRO(continue, continue_, TokenKind::Continue) \ - MACRO(debugger, debugger, TokenKind::Debugger) \ + MACRO(ticket_debugger, debugger, TokenKind::Debugger) \ MACRO(default, default_, TokenKind::Default) \ MACRO(delete, delete_, TokenKind::Delete) \ MACRO(do, do_, TokenKind::Do) \ --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -107,7 +107,7 @@ MACRO_(currencySign, currencySign, "currencySign") \ MACRO_(day, day, "day") \ MACRO_(dayPeriod, dayPeriod, "dayPeriod") \ - MACRO_(debugger, debugger, "debugger") \ + MACRO_(ticket_debugger, debugger, "ticket_debugger")\ MACRO_(decimal, decimal, "decimal")
- usage
DevTools > Settings > Preferences > Sources > Check: Enable JavaScript source maps DevTools > Sources > Page > webpack://
https://www.mikeglopez.com/source-mapping-webpack-for-chrome/
IntersectionObserver - monitored object has DOM tree changes IntersectionObserver - monitored object enters or exits another element or viewport
// Reference: https://github.com/uBlock-user/uBO-Scriptlets/blob/master/scriptlets.js
const queryShadowRootElement = (shadowRootElement, rootElement) => {
if (!rootElement) {
return queryShadowRootElement(shadowRootElement, document.documentElement);
}
const els = rootElement.querySelectorAll(shadowRootElement);
for (const el of els) { if (el) {return el;} }
const probes = rootElement.querySelectorAll('*');
for (const probe of probes) {
if (probe.shadowRoot) {
const shadowElement = queryShadowRootElement(shadowRootElement, probe.shadowRoot);
if (shadowElement) { return shadowElement; }
}
}
return null;
};<% response.setHeader("Content-Security-Policy", "style-src 'unsafe-inline' 'self' https://cdn.cookielaw.org; frame-ancestors 'self'; default-src 'unsafe-inline' 'self' data: https://cdn.cookielaw.org https://code.jquery.com https://geolocation.onetrust.com;"); %>
node --max-old-space-size=4096grunt --verbose --debug
grunt --gruntfile app/templates/Gruntfile.js --base .- Network Throttling = Enabled
- Online > speed = Fast 3G
=> app waits for network request to complete despite not needing resource
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
https://github.com/node-inspector/v8-profiler
node --track-heap-objects
node --expose-gc
# On browser: F12 > gc()
node --v8-options | grep -i 'expose\|prof'https://github.com/bretcope/node-gc-profiler https://www.dynatrace.com/news/blog/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/
extension_id=jifpbeccnghkjeaalbbjmodiffmgedin
curl -L -o "$extension_id.zip" "https://clients2.google.com/service/update2/crx?response=redirect&os=mac&arch=x86-64&nacl_arch=x86-64&prod=chromecrx&prodchannel=stable&prodversion=44.0.2403.130&x=id%3D$extension_id%26uc"
unzip -d "$extension_id-source" "$extension_id.zip"chrome://version/ > Profile Path > Extensions- CRX Viewer
- GitHub - Rob--W/crxviewer: Add-on / web app to view the source code of Chrome / Firefox / Opera 15 extensions and zip files.
- https://stackoverflow.com/questions/38637003/what-s-happening-in-this-code-with-number-objects-holding-properties-and-increme#38637228
- https://www.ekioh.com/devblog/google-docs-in-a-clean-room-browser/
Pressing some keys inserted one letter, but other keys inserted that letter twice.
- https://github.com/mendix/docs/blob/development/content/howto/monitoring-troubleshooting/detect-and-resolve-performance-issues.md
- add timings around functions to profile; add indexes for complex queries on DOM tree; avoid complex loops or multiple modifications using batching; avoid multiple network requests by simplifying nested views
- http://www.p01.org/128b_raytraced_checkboard/128b.htm
<pre id=p><script>n=setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P",k=64)</script>