Improve asset type icon management#1098
Open
tobmes42 wants to merge 16 commits into
Open
Conversation
* Fixed order of authentication methods for timeline filter endpoint. * [ADD] Datastore and my profile support v2 * [ADD] Added missing files * [ADD] Added search on all case elements * [IMP] Improved global search * [ADD] v2 activities endpoint with paging, scope and filters * [IMP] Deduplicate activities within a one-minute bucket * [ADD] v2 endpoints for Dim (Celery) tasks listing and detail * [ADD] v2 endpoints for case close and reopen * [FIX] Detach alert-shared IoCs before deleting a case * [IMP] Independent open/close date bounds for case filters * [ADD] v2 endpoints for managing modules and their hooks * [ADD] v2 endpoints for customer contacts CRUD and embed contacts in customer detail * [FIX] Paginated v2 envelope returns the next page number instead of a boolean * [ADD] Search query parameter on the v2 customers listing endpoint * [ADD] v2 endpoints for the Case Objects taxonomy family backed by a shared CRUD class * [ADD] v2 CRUD endpoints for case templates accepting plain JSON bodies * [ADD] v2 endpoint exposing the introspected case template schema for interactive editors * [ADD] v2 endpoints for report templates including render-against-case with user case-access gating * [ADD] v2 endpoint to replace a report template's file in place via multipart PUT * [ADD] v2 access-control endpoints covering users, groups, members, case-access, customers, audit, MFA reset and API-key rotation * [ADD] v2 read-only endpoints for severities, TLP, alert statuses + resolutions, analysis statuses, event categories and task statuses * [ADD] v2 server settings endpoints with versions block, partial-update PUT and POST backup, deprecating the legacy /manage/settings routes * [UPD] Updated dash and activities * [FIX] Fixed GHSA-g588-5gmf-p5cx by excluding MFA secrets and webauthn credentials from user schemas and marking sensitive fields load-only Backport of f1d41f4 from v2.4.29. UserSchema, UserFullSchema, and BasicUserSchema were leaking mfa_secrets and webauthn_credentials in serialized responses, letting an attacker bypass MFA or impersonate the user (CWE-201, SBA-ADV-20260126-04). user_password is now load-only on UserSchema, and DSFileSchema.file_local_name (server-side path) is declared load-only at the schema layer instead of being del'd in the route handler. The matching v2 schema (UserSchemaForAPIV2) already had these guards; this commit aligns the legacy schemas still in use. * [FIX] Fixed GHSA-w78h-mx7h-qm3h by allowlisting writable fields on user, profile and taxonomy admin endpoints Backport of f84b7b9 from v2.4.29, extended to cover the v2 surface that didn't exist when the original fix shipped. The legacy /manage/users, /manage/asset-type, /manage/ioc-types, /profile/update endpoints accepted the raw request body and handed it straight to the marshmallow schema. The schemas' `unknown = EXCLUDE` drops unknown keys but every declared field on the schema is still accepted — so a caller could overwrite the primary key (mass-assignment of asset_id / type_id), self-promote to admin via user_isadmin on the profile endpoint, or set arbitrary attributes the GUI never exposes (SBA-ADV-20260128-01 / CWE-915). Each writable endpoint now goes through an explicit per-resource allowlist before the schema is loaded. The taxonomy CRUD on rest/v2/manage_routes/case_objects.py declares the allowlist on the shared TaxonomyConfig so the asset-type, ioc-type, classification, state and evidence-type sub-blueprints all inherit the protection without duplication. GHSA-g588 already made user_password load_only on UserSchema, so the legacy /manage/users/add no longer needs the `del udata['user_password']` guard either; remove it. * [FIX] Fixed GHSA-vjc3-7jwv-j9qf by tightening the post-login next-url allowlist Backport of 371c640 from v2.4.29, adapted to develop's _is_safe_url in business/auth.py. The previous check only verified that urlparse(target).scheme and urlparse(target).netloc were empty. urlparse treats `attacker.com?cid=1` as a path with an empty netloc, so the guard accepted attacker-controlled hosts; browsers resolving the resulting `Location: attacker.com` header route the user to the attacker's origin (CWE-601 / SBA-ADV-20260126-02). _is_safe_url now requires the target to be a non-empty string starting with a single `/` (rejecting both protocol-relative `//evil.com` and backslash variants like `/\\evil.com`) and free of control characters, with the urlparse check kept as defense in depth. * [FIX] Fixed GHSA-qhqj-8qw6-wp8v by confining datastore file ops to DATASTORE_PATH and allowlisting writable upload fields Backport of 57c1b80 from v2.4.29, extended to the v2 datastore route that didn't exist when the original fix shipped. datastore_delete_file and datastore_get_local_file_path now resolve the recorded file_local_name and refuse to operate on a path outside the configured DATASTORE_PATH. Even though the dsf row is legitimately fetched through (file_id, case_id), a stored path pointing elsewhere (stale row from a different mount, attacker-seeded value) would let an unlink or send_file escape the datastore — CWE-22. The legacy /datastore/file/add + /datastore/file/update routes and the v2 add_file + update_file methods now project the multipart form down to an allowlist before the schema is loaded, blocking mass-assignment of file_id, file_local_name, file_case_id, file_sha256, file_size, added_by_user_id, file_date_added and friends. * [FIX] Fixed GHSA-8hwq-v6vm-9grr by blocking alert re-attribution and requiring POST on logout Backport of b202f54 from v2.4.29, extended to cover the v2 alerts update endpoint that didn't exist when the original fix shipped. Alert update (legacy single + batch, and v2 PUT /alerts/<id>) now strips alert_id, alert_customer_id and alert_creation_time from the payload before the schema is loaded. Allowing those via the API let a user with write access to one customer re-attribute an alert to a customer they cannot see — silently hiding it from the rightful owner and planting it under another tenant's view (CWE-863 / SBA-ADV-20260128-05). The logout endpoint moves from GET to POST. A plain <img src="/logout"> on a third-party page would otherwise log the user out without consent (RFC 7231 §4.2.1: GET must be safe; CWE-650 / SBA-ADV-20260128-03). The sidenav link wraps a hidden form so existing accessibility / styling keeps working. * [FIX] Sanitised HTML custom attributes via bleach and forced unsafe datastore downloads as attachments * [FIX] Moved no-cache headers into the server block and added long-lived caching for /static * [DEL] Removed GraphQL surface and dependencies — GHSA-3mxh-x92q-9r25 * [UPD] Bumped iris-webhooks to 1.0.9 and hardened docker base images with apt upgrade * [FIX] Fixed access control ordering so group access overrides customer access on cases * [ADD] Added 'neq' and 'not_like' operators to the filter condition builder * [FIX] Tagged alert comment edits as 'alerts' instead of 'events' so activity attribution is right * [FIX] Hardened MFA flow with session-bound user, server-side secret, lockout and allowlisted DS file_tags * [ADD] Added statistics_read and custom_dashboards_{read,write,share} permission bits * [UPD] Folded statistics_read into custom_dashboards_read so Statistics ships as a seeded dashboard * [ADD] Added /api/v2/dashboard/kpis with the compact KPI block for the home tile * [ADD] Added CustomDashboard and CustomDashboardWidget models with migration seeding the Statistics system dashboard * [ADD] Added custom dashboard query engine schema and named-aggregation registry for MTTD MTTR false-positive escalation and sliding-window metrics * [ADD] Added /api/v2/custom-dashboards endpoints for CRUD render schema and presets with system-dashboard guard * [ADD] Added pytest suite for custom-dashboards CRUD render system-guard and ownership scoping * [FIX] Imported ac_current_user_has_permission from blueprints.access_controls where develop actually defines it * [FIX] Deferred get_user import in business.access_controls to break circular import with manage_users_db * [FIX] Reconciled pre-existing custom_dashboard table by adding missing is_system column and relaxing owner_id NOT NULL before seeding * [FIX] Accept is_system and filters_schema in CustomDashboardSchema and ignore unknown widget/section keys so the seed Statistics dashboard renders * [FIX] Dropped duplicate group-column field from seed Statistics widgets so charts render one dataset with category x-axis instead of one dataset per category * [IMP] Returned rendered widgets grouped by section so the view page can preserve section titles dividers and ordering * [FIX] Skipped duplicate-label projection in the query engine so widgets that name the same column in fields and group_by render one column not two * [ADD] Added /api/v2/me/context endpoint returning iris_version demo_mode and effective permissions so the SPA can gate menu entries and show the running version without giving every user server_administrator access * [ADD] Added migration that idempotently creates the saved_filters table so deployments where db.create_all never ran (or where a partial restore skipped it) can persist alerts and cases saved filters * [ADD] Added /api/v2/cases-filters endpoints (list create get update delete) reusing the alerts saved-filter business layer with filter_type='cases' so the cases overview can persist private and public filter presets * [IMP] Made the cases filter endpoint accept a recursive group tree ({logic items}) on top of the legacy flat list and rewrote build_filter_case_query to walk the tree so the UI can express (A and B) or (C and D) style queries and also added a severity column to the advanced filter switch * [FIX] Enforce ownership on saved-filter PUT and DELETE in both alerts-filters and cases-filters so a user who can read a public filter cannot mutate someone else's row and force created_by from the session user on PUT to block mass-assignment * [FIX] Made the alembic helper functions reuse op.get_bind() instead of spinning up a fresh engine per call so a single migration boot no longer leaks several SQLAlchemy connection pools and exhausts Postgres max_connections with FATAL sorry too many clients already mid-startup * [ADD] Added avatar_blob avatar_mime and avatar_updated_at columns to the user table with an idempotent migration so each user can store their profile picture as a normalised 256x256 PNG that the SPA can fetch from a single endpoint * [ADD] Added avatar endpoints (GET users id avatar for anyone authenticated POST DELETE me avatar for self-service POST DELETE manage users id avatar for admins) with Pillow normalisation to 256x256 PNG dropped avatar_blob from the User schemas to keep bytes out of JSON dumps and surfaced user_id on the per-case activities feed so the activity panel can attach the right avatar to each row * [FIX] Allowed blob: in img-src CSP nginx headers so authenticated avatar object URLs render * [ADD] Exposed note revisions on v2 (list get delete restore) and added notes_restore_revision so the SPA can re-list every snapshot taken on each note edit and roll the title and body back to any prior version * [ADD] v2 admin endpoints for the CustomAttribute taxonomy * [ADD] expose has_mini_sidebar in /me/context and a PUT /me/preferences to persist UI preferences * [ADD] v2 endpoints to list other cases where an IOC or asset was previously seen * [ADD] Enforce MFA verification on token-authenticated endpoints with brute-force throttle, re-enrollment guard, refresh propagation and integration tests * [ADD] user followed cases + multiple named timelines per case * [ADD] war room foundation: models, ACL, REST CRUD + case attachment + members * [ADD] war room chat/tasks/notes/timelines/graph/sitreps/datastore REST + business * [FIX] emit war-room activity events from REST mutations (attach/detach/members/tasks/notes) * [ADD] war room chat activity_type column + inference; classify case activity for fine-grained stream filtering * [ADD] live-merge UserActivity into war-room stream; drop chat-side activity_type column dependency * [REM] war room graph board (models, REST, business, migration drop) * [ADD] war room: customer name on case attachments, creator/closer attribution on tasks * [ADD] more war-room slash commands (/decision /assign /detach /state /priority /summary /whoami /help) * [FIX] war-room stream: explicit error on unknown / failing slash commands (no more silent fall-through to literal /text storage) * [ADD] war-room cases enrich (owner/dates/state/tasks) + /people endpoint; surface generic slash-error refs * [REM] /whoami slash command (low signal) * [FIX] add PATCH to CORS Access-Control-Allow-Methods (war-room update + every v2 PATCH endpoint was blocked by preflight) * [ADD] war-room timeline event PATCH + category column + drag-between-timelines support * [ADD] war-room Stream threads — parent_message_id + thread_title columns + follower table + /thread slash + reply/follow/retitle endpoints (gated on pre-migration DBs) * [FIX] war-room threads support probe — use fresh engine connection, don't pin negative result so a freshly-applied migration is picked up without restart * [ADD] /api/v2/cases/{id}/access/me endpoint + allow read_only access on notes_directories.search (was full_access only — broke read-only users' notes view) * [IMP] bump postgres image to 18-alpine + add pg12→pg18 migration script and 3.0.0 upgrade notes * [IMP] threads-support probe queries the column directly on a fresh connection — search_path / inspector-cache issues were giving spurious negatives; distinguish UndefinedColumn (42703) from other DB errors in logs * [FIX] /me/followed-cases — use CaseSchemaForAPIV2 so dashboard tile gets case_name + case_customer * [REM] evtx2splunk + iris_evtx module — drop the two wheels, evtxdump_binaries, requirements entries, and the Dockerfile chmod step * [FIX] PG18 PGDATA path — pin to /var/lib/postgresql/data/pgdata in compose and upgrade script (image refuses mountpoint-as-PGDATA) * [ADD] pass VITE_ALLOWED_HOSTS + make ORIGIN overridable in frontend service * [FIX] api_auth — return 401 instead of 500 when token/session references a missing user users_get_active() raises ObjectNotFoundError when a JWT or session points at a deleted/inactive user, which propagated to the Flask exception handler and logged a 500 on routine calls like POST /auth/logout. Wrap the lookup so the JWT path reports "invalid" (401) and the legacy/session paths fall through as unauthenticated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * [ADD] search — case summaries as a new searchable type in /search * [FIX] cases overview — Tags filter was silently dropped; wire it via EXISTS(CaseTags JOIN Tags) * [FIX] post_init — only seed default group permissions on first creation; admin edits no longer reset on worker boot * [FIX] AuthorizationGroupSchema — respect partial PATCH; don't wipe group_permissions when the key is absent * [IMP] war-room sitreps — publish is a state marker only; edit and delete stay allowed after publish * [ADD] war-room chat — /decision, /pin, /note as thread replies; trace-log endpoint; server-side search on /chat * [FIX] alembic env — restore context.begin_transaction() so migrations actually commit * [ADD] war-room archive — archived_at/by columns, list filter, archive/unarchive endpoints, open-first sort * [ADD] per-user preferences — user.preferences JSONB + /users/me/preferences/<key> endpoints * [ADD] OIDC session→JWT exchange endpoint + provider discovery fallback + single-use session flag * [ADD] nginx cert autodetect + reload polling, CA-bundle drop-in dir, IRIS_HOSTNAME single-source-of-truth, certbot deploy-hook * [ADD] docker-compose.new-ui overlay + frontend Dockerfile for the SvelteKit UI service * [ADD] notification core — notification/notification_setting tables + service + hook listeners + /api/v2/notifications endpoints + /notifications SocketIO namespace + /users/mentionable directory for analyst mention search * [ADD] incidents + investigation flows (self-conditioned, alert/incident/both target, deploy-to-existing) + incident-rules with nested AND/OR conditions, back-fill, JSONB path support (alert_context.foo.bar) * [FIX] enforce customer-scope authorisation on incident-rules + investigation-flows (getters/list/create/update/deploy/backfill), server-owned rule_created_by/flow_created_by attribution, public proxies for cross-module access-control helpers * [IMP] incidents: comments, audit trail, incident_id alert filter, incident-statuses endpoint, escalate crash fix * [ADD] mail: inbound ingest + outbound send with rules engine and secrets manager * [FIX] pg12-to-pg18 upgrade: preserve hyphens in compose project name and detect stopped iriswebapp_db container * [IMP] activity log: cover war rooms + case timelines + admin modules, add war_room_id scoping and /_diag notifications endpoint * [FIX] compose: disable adapter-node BODY_SIZE_LIMIT so multi-MB avatar and multi-GB datastore uploads aren't truncated * [FIX] notifications: drop /_diag endpoint and remove UserActivity.war_room relationship that broke gunicorn boot (WarRoom unresolvable at mapper-config time) * [ADD] on_postload hooks for war room and incidents * [IMP] incidents: escalate/merge to case, propagate status to alerts, expose source-incident on cases * [ADD] incidents: correlation graph endpoint, unlink alert/incident from case, business helpers * [ADD] collab: server-side Yjs relay, per-doc rooms, socket JWT-in-auth fallback * [FIX] collab: GFM tables in seeder + auto re-seed via seeder_version bump * [FIX] collab: unflatten single-line GFM pipe tables from legacy imports * [IMP] rename Incident -> AlertCluster, IncidentRule -> ClusterRule across models, migrations, business, REST, schemas, hooks, celery tasks, tests --------- Co-authored-by: fatpeppapig <cezary@falba.net> Co-authored-by: whitekernel <74464599+whikernel@users.noreply.github.com> Co-authored-by: whitekernel <whitekernel@dfir-iris.org> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…compromised assets
… handle duplicates
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem:
When creating or editing an asset type (AssetsType) via the Web GUI, several limitations existed:
Changes:
GUI / User Experience (modal_add_asset_type.html + manage.objects.js):
Backend / REST API (manage_assets_type_routes.py):
Icon Storage (marshables.py):
Icon Listing (manage_assets_type_routes.py – Pages):
Affected files: