سوالات در مورد رفتار مناسب با changeset در الکسیر

درود خدمت دوستان و اساتید محترم . در این پست می خوام سوالاتی که در مورد changeset دارم رو به مرور بپرسم.

اولین سوال من به شرح زیر هست :

من از کاربر اطلاعاتی از جمله یوزر و پسورد رو دریافت می کنم در هنگام ثبت نام . می خوام این بره تو changeset من و کاملا ولید شد و اگر ارور نداشت پسورد از حالت نرمال بیاد تبدیل به پسورد انکریپت شده بشه.

حالا سوال اینجاست که من باید این کارو در خود changeset انجام بدم یا به صورت زیر انجام دادم مناسب است .

قطعه کد من

		case Repo.insert(changeset) do
		  	{:ok, post} -> 
		  		edit_user(post.id, %{password: Comeonin.Bcrypt.hashpwsalt(post.password)}) 
#
		  	{:error, changeset} ->  changeset    
		end

در کد بالا بعد از اینکه ارسال شد سریعا ویرایش می شه و پسورد انکریپت می شه

دلیلی این کارم : هدف بنده این بود که اول تمام شرط هایی که در changeset داشتم انجام بشه بعد از آنکه ولید بود بیام پسورد اینکریپت کنم

با تشکر از از شما :rose:

به قسمت درست کردن password و password_hash نگاه کن

1 پسندیده

ممنون سام عزیز انجامش دادم . فقط یک سوالی داشتم از شما . اون کاری که من کردم چه مشکلی ایجاد می کرد البته فقط برای اطلاعات عمومی هست چون می خوام ویدیو بسازم از کل مواردی که از شما و دوستان دیگر راهنمایی گرفتم . می خوام این مشکلات رو مطرح کنم در ویدیو و راه حل براش درست کنم و برای عموم به اشتراک بزارم

1 پسندیده

پسورد و اگر virtual نکنی ecto فکر میکنه تو دیتابیس فیلدش هستش و میخواهی ذخیره کنی و این طوری پسورد خام بدون hash میتونه بگذاره که هرگز این کارو نباید کنی وقتی پسورد virtual اعلام میکنی ecto اون و در schema تعریف میکنه ولی در دیتابیس نمیگذاره که میتونی hashed password و فقط بعد hash کردن پسورد ذخیره کنی

1 پسندیده

پس به همین منظور بود در ترمینال پسورد رو فیلتر نمی کرد. و پسورد خام رو نشون می داد . فکر کنم .

ممنون سام عزیز

Changeset نمیتونه چیزی رو ولید کنه، دیتا باید ولید باشه وگرنه changeset فقط میتونه validate کنه و ارور بده.
در مورد virtual attribute یا virtual fields که در پرسش شمامیتونه password باشه @samdvr همه چیزو گفت اما میتونی از لینک زیر بیشتر اطلاعات بگیری.

https://til.hashrocket.com/posts/5a1c28f560-virtual-fields-with-ecto-schema

2 پسندیده

پست کامل شد :point_up_2:

1 پسندیده

توماج جان اول گفتی ولید نمی تونه بکنه بعد در آخر گفتید فقط می تونه validate کنه من گیج شدم …
من منظور این بود که شرط هایی که در چنج ست هست همه انجام بشه و اگر ولید بود مثل اندازه کارکتر ها یا موارد سفارشی مثل چک کردن پسورد خودم نوشتم , در آخر اگر همه ولید بوداینکریپشن هم انجام بشه ولاغیر به مرحله اینکریپشن نرسه

تشکر بخاطر لینک اتفاقا داشتم همین الان سرچ می کردم ببنیم چه کار های دیگه ای از ecto بر می یاد :grin:

1 پسندیده

آهان الان متوجه شدم، منظور شما رو از ولید متوجه نشدم فکر کردم میگی مثلا اگر پسورد مناسب نیست اکتو تغییرش بده.

Valid != validate

1 پسندیده

فارسی که می شه کمی میره بر تفاوت اشتباه از بنده بود :grin:
ببخشید :rose:

نه مشکلی نیست، بعضی از واژها تفا‌وت خیلی زیادی ایجاد میکنند برای همین اشتباه کردم، هر دانشی دایره واژگانی داره که اگر درست استفاده نشه دیگه بحث در زمینه اون دانش معنی نمیده،
همونطور که میدونید دو تا زبان برای ارتباط برقرار کردن بین انسان ها وجود داره؛
formal language و natural language
اولی زبان دانش هست که مجموعه ای از واژگان و اصطلاحات علمیه که هر کدوم معنی کاملا مشخصی داره.
دومی زبان گفتگو و محاوره.

1 پسندیده

درود خدمت دوستان محترم .

یک سوالی برام پیش اومده که می خواستم ببنیم شما عزیزان چیکار می خواهید بکنید . می خواستم یک تابع درست کنم و در changeset اضافه کنم که اگر کارکتر های غیر مجاز در اسم بود نزاره ذخیره بشه ولی سوال اینجاست

۱. آیا شما در موقع ارسال به دیتابیس این کارو می کنید . یا در زمانی که می خواهید خروجی در html نشون بدید سنتایز می کنید ؟
۲. بعید می دونم باگ xss خروجی json رو متاسر کنه و مشکلی ایجاد کنه درسته ؟

1 پسندیده

درود خدمت دوستان من بخشی از سوالمو در لینک زیر هم پرسیدم باز اگر شما عزیزان نیز نظری دارید ممنون می شم

با تشکر

1 پسندیده

من دیشب پاسخ دادم اما چون سوال چند موضوع رو با هم به طرز کاملا بی رحمانه ای ترکیب کرده کمی گیج شدم،
اول همونطوری که عرض کرده بودم represantation context مهمه، اما وقتی از json api استفاده میکنیم ممکنه که بصورت embeded در جایی که قابلیت اجرای script و‌sniff کردن داره بکار برده بشه، من فکر میکنم باید جلوی sql injection در زمان ساختن کوئری گرفته بشه اگر نگران injection به سرویس خودت هستی. اما sanitize کردن وردی در کنار ولیدیشن میتونه جلوی خیلی از ریسک ها رو بگیره. اگر ورودی قراره که تگ html داشته باشه میتونیم تگ ها رو whitelist کنیم
https://hexdocs.pm/phoenix_html/Phoenix.HTML.html

1 پسندیده

شرمنده :grin: خودمم متوجه شدم حتی چند بار تغییر دادم . متاسفانه اون پیغام شما رو من تا برسم حذف شده بود نتونستم بخونمش .

همانطور که از صحبت شما متوجه شدم و پستی که در انجمن الکسیر زدم . در خود خروجی json مشکلی به وجود نمی یاد خودش با / و … اسکیپ می کنه در جایی که داریم از این خروجی json استفاده می کنیم مثلا در یک صفحه html اونجاست که ممکنه مشکل بشه درسته ؟

اینو متوجه نشدم . با پست طرف هم همینرو متوجه نشده بودم

مگه ecto جلوشو نمی گیره ؟ منظورم sql injection هست ؟
علاوه بر اون من یک مقدار ولیدیشن های ضروری و همینطور رجکس نیز نوشتم که تا اونجایی که ممکنه جلوی شیطونی کاربر رو بگیرم

ممنون . این در زمانی هست که من از جایی دارم json می گیرم و می خوام مثلا بیارم در فونیکس در یکی از view ها استفاده کنم درسته ؟ اونجاست که باید سنتایز کنم ولی اصل خروجی json براش مشکلی پیش نمی یاد ؟

فکر نمیکنم کلا بحث ما در مورد json باشه چون json فقط یک تایپ هست، بحث بیشتر بر سر api و تبادل دیتاست و شیوه استفاده از اون دیتا. تا زمانی که شما مستقیم از داده های کاربر برای کوئری کردن دیتابیس استفاده نکنید یا با رعایت موارد امنیتی استفاده کنید مشکل sql injection پیش نمیاد.
منظور از sniff کردن در موضوع مورد بحث ما mime sniffing هست که با X-Content-Type-Options: nosniff میشه جلوشو گرفت + Content-Type.

من نگفتم اکتو جلوی injection رو میگیره یا نه, همونطور که قبلا هم بحث شد ecto هم روش مشابهی داره که همون جلوگیری از injection در زمان ساختن کوئری هست, در ضمن در ecto هم میشه با استفاده بد راه حمله رو باز کرد.
ecto جلوی injection رو نمیگیره اما مثل بیشتر ORM ها ابزاری در اختیار شما میزاره که شانس sql injection رو از بین ببرید.
یعنی اگر از متد های Echto.Query برای compose کردن query استفاده کنید, امن خواهد بود
https://hexdocs.pm/ecto/Ecto.Query.html

1 پسندیده

انقدر بحث های در این موارد برام جذاب هست توماج جان که نمی دونم چرا از xss رفتیم توی sql injection ولی بسیار هم خوب شد ولی من یک سوال پایه از شما بپرسم ورای تمام صحبت های بالا

این خروجی رو ببنید

iex(1)> Poison.encode %{"test" => "<script>alert('g')</script>"}
{:ok, "{\"test\":\"<script>alert('g')</script>\"}"}

تا در زمانی که در یک html فراخوانی نشه مشکلی ایجاد نمی کنه درسته ؟ مثلا در صفحه .json فقط یک رشته معمولی هست و قدرت عملیاتی نداره درسته ؟

1 پسندیده

اگر مرورگر بیش از حد باهوش نباشه و script با js engine رندر نکنه :face_with_thermometer: خیر مشکلی ایجاد نمیشه، اما اگر script در جایی که js رندر میشه embed بشه مثلا توی یک single page app, میتونه یک ریسک باشه. واقعا فکر نمیکنم در json endpoint مشکلی وجود داشته باشه, این موضوع اصلا مربوط به جایی میشه که دیتا مصرف و پردازش میشود :rotating_light:

حالا وقتی decode و parse میکنی چه اتفاقی میوفته؟

%{ "test" => "<script> Devil’s dance! </script>" }

—————-

https://hexdocs.pm/elixir/IO.html#iodata_to_binary/1

اگر تست کنی و نتیجه رو بگی خیلی خوب میشه، ممکنه Poison بهتر از اونی باشه که فکر میکنیم.

test کلید مناسبی نیست حتا برای test :wink: بخصوص وقتی پرسشی وجود داره چون موضوع رو مخفی میکنه.

1 پسندیده

درود توماج جان تست کردمش البته توی ترمینال

iex(2)> {:ok, body} = Poison.encode %{"body" => "<script>alert('g')</script>"}
{:ok, "{\"body\":\"<script>alert('g')</script>\"}"}
iex(3)> body
"{\"body\":\"<script>alert('g')</script>\"}"
iex(4)> Poison.decode body
{:ok, %{"body" => "<script>alert('g')</script>"}}

اگر نیاز هست بفرمایید در صفحه ای فونیکس درست کنم از اول در یک ویو هم لود کنمش ؟

با مرورگر هم تست کنی بد نیست، چون بازم باید داده به json تبدیل بشه

1 پسندیده